#include "SearchCore.h"
#include <stdlib.h> 
//#include "MrUtilDebug.h"

Array iMultiPyCodeSorted;
BOOL iIsMultiPYinWordsLoaded = FALSE;

int SIZEOF_INT = sizeof(int);
int SIZEOF_U2Char = sizeof(u2char);
int SIZEOF_WordCode = sizeof(WordCode);
int SIZEOF_SearchData = sizeof(SearchData);
int SIZEOF_SearchPos = sizeof(SearchPos);
int SIZEOF_SearchSort = sizeof(SearchSort);

//kmp比较需缓存
int iKmpBuf[128];

int searchPosMallocSize = 0;
SearchPos *searchPosMalloc = NULL;
int searchPosPtrMallocSize = 0;
SearchPos **searchPosPtrArray = NULL;
Array searchPosMallocArray;

//enum {ID_Ascii = 0,ID_PinYinCode = 1,ID_CharIndex = 2,ID_CharIndex2 = 3,ID_CannotSpell = 4};

BOOL isPinYinCodeIndexSorted = FALSE;
int PinYinCodeIndexSort[KPyCodeNum];
int PinYinNum[KPyCodeNum];

//汉字基本发音表   
const   char   *PinYinCode[KPyCodeNum]   =     
{
        "a",   "ai",   "an",   "ang",   "ao",   "ba",   "bai",   "ban",   "bang",   "bao",
		"bei",   "ben",   "beng",   "bi",   "bian",   "biao",   "bie",   "bin",   "bing",   "bo",   
		"bu",   "ca",   "cai",   "can",   "cang",   "cao",   "ce",   "ceng",   "cha",   "chai",   
		"chan",   "chang",   "chao",   "che",   "chen",   "cheng",   "chi",   "chong",   "chou",   "chu",   
		"chuai",   "chuan",   "chuang",   "chui",   "chun",   "chuo",   "ci",   "cong",   "cou",   "cu",   
		"cuan",   "cui",   "cun",   "cuo",   "da",   "dai",   "dan",   "dang",   "dao",   "de",   
		"deng",   "di",   "dian",   "diao",   "die",   "ding",   "diu",   "dong",   "dou",   "du",   
		"duan",   "dui",   "dun",   "duo",   "e",   "en",   "er",   "fa",   "fan",   "fang",   
		"fei",   "fen",   "feng",   "fu",   "fou",   "ga",   "gai",   "gan",   "gang",   "gao",   
		"ge",   "ji",   "gen",   "geng",   "gong",   "gou",   "gu",   "gua",   "guai",   "guan",   
		"guang",   "gui",   "gun",   "guo",   "ha",   "hai",   "han",   "hang",   "hao",   "he",   
		"hei",   "hen",   "heng",   "hong",   "hou",   "hu",   "hua",   "huai",   "huan",   "huang",   
		"hui",   "hun",   "huo",   "jia",   "jian",   "jiang",   "qiao",   "jiao",   "jie",   "jin",   
		"jing",   "jiong",   "jiu",   "ju",   "juan",   "jue",   "jun",   "ka",   "kai",   "kan",   
		"kang",   "kao",   "ke",   "ken",   "keng",   "kong",   "kou",   "ku",   "kua",   "kuai",   
		"kuan",   "kuang",   "kui",   "kun",   "kuo",   "la",   "lai",   "lan",   "lang",   "lao",   
		"le",   "lei",   "leng",   "li",   "lia",   "lian",   "liang",   "liao",   "lie",   "lin",   
		"ling",   "liu",   "long",   "lou",   "lu",   "luan",   "lue",   "lun",   "luo",   "ma",   
		"mai",   "man",   "mang",   "mao",   "me",   "mei",   "men",   "meng",   "mi",   "mian",   
		"miao",   "mie",   "min",   "ming",   "miu",   "mo",   "mou",   "mu",   "na",   "nai",   
		"nan",   "nang",   "nao",   "ne",   "nei",   "nen",   "neng",   "ni",   "nian",   "niang",   
		"niao",   "nie",   "nin",   "ning",   "niu",   "nong",   "nu",   "nuan",   "nue",   "yao",   
		"nuo",   "o",   "ou",   "pa",   "pai",   "pan",   "pang",   "pao",   "pei",   "pen",   
		"peng",   "pi",   "pian",   "piao",   "pie",   "pin",   "ping",   "po",   "pou",   "pu",   
		"qi",   "qia",   "qian",   "qiang",   "qie",   "qin",   "qing",   "qiong",   "qiu",   "qu",   
		"quan",   "que",   "qun",   "ran",   "rang",   "rao",   "re",   "ren",   "reng",   "ri",   
		"rong",   "rou",   "ru",   "ruan",   "rui",   "run",   "ruo",   "sa",   "sai",   "san",   
		"sang",   "sao",   "se",   "sen",   "seng",   "sha",   "shai",   "shan",   "shang",   "shao",   
		"she",   "shen",   "sheng",   "shi",   "shou",   "shu",   "shua",   "shuai",   "shuan",   "shuang",   
		"shui",   "shun",   "shuo",   "si",   "song",   "sou",   "su",   "suan",   "sui",   "sun",   
		"suo",   "ta",   "tai",   "tan",   "tang",   "tao",   "te",   "teng",   "ti",   "tian",   
		"tiao",   "tie",   "ting",   "tong",   "tou",   "tu",   "tuan",   "tui",   "tun",   "tuo",   
		"wa",   "wai",   "wan",   "wang",   "wei",   "wen",   "weng",   "wo",   "wu",   "xi",   
		"xia",   "xian",   "xiang",   "xiao",   "xie",   "xin",   "xing",   "xiong",   "xiu",   "xu",   
		"xuan",   "xue",   "xun",   "ya",   "yan",   "yang",   "ye",   "yi",   "yin",   "ying",   
		"yo",   "yong",   "you",   "yu",   "yuan",   "yue",   "yun",   "za",   "zai",   "zan",   
		"zang",   "zao",   "ze",   "zei",   "zen",   "zeng",   "zha",   "zhai",   "zhan",   "zhang",   
		"zhao",   "zhe",   "zhen",   "zheng",   "zhi",   "zhong",   "zhou",   "zhu",   "zhua",   "zhuai",   
		"zhuan",   "zhuang",   "zhui",   "zhun",   "zhuo",   "zi",   "zong",   "zou",   "zu",   "zuan",   
		"zui",   "zun",   "zuo",   "",   "ei",   "m",   "n",   "dia",   "cen",   "nou",   
		"jv",   "qv",   "xv",   "lv",   "nv" ,  "fo"  
};   

/*
 * unicode汉字拼音码序号
 * 取值说明：
 * 0: 未能识别
 * 1-405: 对应于PinYinCode拼音码表的序号
 */

const   long PyCodeIndex[82][256]   = 
{
	{348,66,354,241,279,331,0,323,370,270,279,331,92,21,354,190,87,39,39,381,245,232,284,284,249,19,347,48,68,294,36,67,249,167,67,353,167,345,19,271,286,133,91,344,382,376,92,129,83,152,42,31,170,385,63,105,323,57,325,378,131,164,134,235,84,348,348,200,329,133,133,320,185,348,0,375,329,367,116,78,161,376,237,227,127,116,99,283,36,348,349,344,212,133,241,347,330,333,87,133,0,0,286,0,284,92,202,0,0,0,0,0,181,176,0,263,342,345,0,276,199,243,0,0,52,0,243,375,102,88,176,170,348,136,161,180,354,374,375,284,77,40,354,153,354,357,116,241,329,131,294,299,93,94,344,335,344,368,344,92,326,324,141,55,128,106,348,31,113,198,347,333,131,313,167,333,131,347,246,20,353,335,369,166,74,325,258,57,92,0,329,348,282,258,161,66,363,130,240,39,6,370,130,129,19,259,48,0,306,178,0,25,359,284,302,370,84,332,332,372,114,314,258,243,107,348,20,56,171,348,33,370,268,279,348,198,187,258,79,191,346,243,376,232,328,329,125,124,220,83,43,258,324,82,62,80},
	{376,241,229,354,64,73,329,348,336,141,348,92,2,329,92,84,78,339,349,232,282,84,305,376,353,123,121,354,389,357,270,325,42,134,344,332,279,32,178,25,343,336,325,378,363,332,217,20,97,208,208,335,8,340,171,377,282,389,294,13,284,86,232,348,294,348,374,63,107,181,57,378,21,250,14,371,47,325,62,378,393,353,346,309,369,110,14,320,281,354,348,406,393,96,214,314,208,332,250,352,321,243,284,138,10,229,121,110,160,333,91,346,7,78,194,124,77,19,92,113,123,102,251,311,128,47,348,284,337,282,320,140,375,106,157,348,37,149,101,164,349,284,189,378,340,353,3,175,197,77,178,68,29,37,343,95,377,348,263,125,331,294,56,404,302,220,373,27,127,150,30,214,216,130,329,115,132,313,373,393,39,246,404,134,286,313,282,320,20,201,334,15,318,354,330,50,75,249,340,101,148,329,137,348,84,167,389,127,164,352,122,350,332,270,229,297,84,330,164,190,237,10,354,294,331,336,339,354,62,134,39,375,345,167,164,157,294,125,339,84,123,134,334,225,125,16,309,81,83,344,3,11,354,336,14,116},
	{374,375,19,133,220,389,167,323,169,43,387,91,100,11,310,286,286,187,59,304,136,383,337,237,305,115,348,241,309,88,167,129,299,32,245,80,375,146,135,387,134,243,208,178,385,328,179,295,171,122,68,386,12,329,134,200,23,125,368,347,375,276,247,245,350,36,243,345,264,376,45,124,92,325,354,19,267,309,325,233,345,83,305,328,75,335,34,283,140,62,393,29,313,11,367,120,220,369,388,345,353,125,340,367,47,84,84,375,387,190,92,348,335,343,294,71,368,373,223,315,315,11,360,404,245,325,82,32,153,296,375,297,331,84,355,261,164,217,357,126,180,9,63,305,109,129,330,278,243,252,35,40,270,11,334,352,220,304,301,346,78,19,333,56,359,305,97,18,40,221,270,162,52,352,362,387,231,295,5,381,354,368,389,279,43,131,37,276,107,370,247,349,62,335,174,11,234,130,166,175,182,243,332,304,350,68,392,333,278,127,132,318,392,240,330,160,32,101,168,241,308,381,325,92,20,121,45,312,278,220,133,275,82,332,354,75,128,125,314,170,20,97,332,297,332,126,193,347,130,242,127,232,83,377,2,269},
	{348,137,216,304,348,58,131,341,150,125,40,57,128,276,359,24,18,3,263,303,59,30,158,348,130,243,188,329,214,248,208,32,169,162,404,152,10,354,16,360,375,294,353,109,247,246,164,308,325,173,40,31,333,311,335,164,179,360,221,305,345,179,202,77,329,357,360,355,338,38,371,338,332,101,265,143,265,190,316,32,208,72,208,130,316,294,345,345,284,0,58,0,69,0,0,282,69,0,131,0,120,263,329,265,251,167,354,6,95,172,330,107,158,95,310,100,337,19,241,134,63,386,0,346,125,285,92,348,92,31,314,184,254,205,345,184,89,254,367,132,27,359,98,132,184,377,184,96,340,190,237,261,353,335,140,137,216,348,189,284,100,188,376,134,355,194,147,193,84,335,189,167,68,303,89,83,19,116,38,136,116,152,347,163,226,84,193,68,332,169,242,125,131,296,186,316,241,97,384,295,131,167,247,64,171,68,88,125,349,49,2,164,25,194,384,52,294,74,130,170,170,214,330,70,92,79,79,79,83,134,40,374,83,198,375,84,83,237,83,139,120,139,88,61,237,278,338,150,316,5,40,92,58,107,107,362},
	{59,64,27,258,258,43,82,245,348,92,140,243,53,40,326,92,57,337,117,323,136,164,356,169,172,363,89,43,84,40,250,64,278,193,171,376,226,17,129,129,228,164,278,17,31,131,98,94,59,43,153,148,74,77,375,287,251,29,47,143,129,102,47,102,139,74,92,309,131,69,179,363,355,54,342,0,156,243,276,43,98,125,54,164,309,81,239,31,241,43,386,89,323,240,92,74,247,345,385,125,92,10,345,134,123,283,125,74,375,329,98,84,283,125,91,367,139,244,42,31,381,175,164,231,278,234,147,128,98,127,136,117,367,385,166,134,232,172,102,128,102,125,125,314,123,92,125,348,125,375,31,390,196,164,378,164,344,251,8,95,124,329,181,169,131,145,335,375,68,378,217,129,250,280,348,378,196,164,130,160,160,135,147,346,321,334,197,152,129,169,110,284,0,131,90,20,193,37,159,352,352,190,0,343,135,247,175,21,188,157,161,139,190,68,340,340,140,329,348,343,346,283,168,198,175,234,284,92,246,244,128,251,333,348,342,79,135,314,134,57,335,181,343,343,404,164,34,333,251,10,280,357,133,10,96,329},
	{357,0,14,87,87,10,48,348,338,231,134,220,91,240,75,228,84,95,55,133,95,14,117,11,203,284,250,133,348,358,126,141,126,152,116,331,250,79,102,245,361,152,81,116,354,102,153,121,57,153,166,166,298,70,133,250,330,232,250,348,143,345,15,208,250,284,343,243,209,268,389,283,329,121,8,284,330,323,117,335,323,11,389,385,335,57,181,201,278,92,20,288,20,152,15,21,369,138,175,353,175,330,98,328,335,57,254,325,346,248,375,184,349,325,280,92,252,176,37,135,335,340,130,330,153,92,75,247,330,270,32,345,75,313,164,372,107,164,344,344,345,281,62,368,227,0,245,344,375,27,183,309,164,281,115,313,391,54,81,355,363,355,333,345,164,136,276,63,40,133,246,5,102,345,294,164,32,243,164,345,345,355,294,114,190,262,250,250,0,162,70,332,381,270,24,282,282,282,348,56,353,29,92,353,290,79,285,136,6,78,267,284,286,385,250,285,15,340,331,226,334,92,357,296,65,265,48,147,97,134,171,98,59,147,375,128,371,6,66,143,303,37,284,353,249,238,347,109,294,304,37,161,64,92,0,114},
	{192,340,183,37,91,341,220,386,110,92,64,74,314,194,115,164,316,333,367,331,347,404,1,180,223,123,348,137,39,170,319,349,81,14,246,246,335,239,85,6,73,82,117,107,313,145,292,241,114,375,349,354,329,33,221,342,330,44,263,326,115,223,329,90,344,137,404,75,91,326,56,241,36,329,90,84,128,357,37,283,199,319,198,348,303,223,164,11,355,104,326,244,329,75,284,135,230,326,204,197,171,254,353,62,377,284,377,312,330,348,241,237,386,98,47,325,340,110,203,86,229,348,334,282,116,194,344,250,134,332,358,320,74,239,228,17,84,346,123,358,110,303,133,352,84,55,377,321,138,97,138,393,21,173,68,214,302,294,332,123,241,77,75,101,367,375,348,169,386,192,189,375,220,92,378,91,343,360,334,143,121,149,284,311,332,397,341,339,322,345,160,348,2,236,282,314,114,338,74,321,105,359,353,189,225,333,2,93,152,344,55,334,14,121,209,117,337,150,74,0,92,216,197,351,109,357,173,239,183,91,222,37,280,164,199,389,110,148,334,332,160,238,372,367,167,6,192,404,299,84,21,107,113,94,356,91},
	{353,345,97,97,11,107,301,45,348,2,243,316,345,323,164,330,305,393,249,34,76,362,344,69,241,62,246,181,0,114,0,0,160,167,301,362,119,159,276,92,0,328,83,349,116,241,285,325,287,32,321,164,244,3,363,351,209,354,310,157,276,330,320,116,2,377,400,144,385,385,279,368,358,170,1,334,333,384,329,326,52,309,97,241,241,306,57,57,347,386,316,52,46,110,344,241,372,81,167,332,232,276,156,363,350,98,224,363,273,381,212,104,179,0,62,251,320,20,66,159,334,0,305,37,309,3,133,57,138,352,325,201,278,354,372,156,129,115,107,367,377,30,322,221,0,349,360,220,328,190,116,357,42,121,119,355,330,110,92,153,376,325,276,340,120,367,345,341,167,354,271,139,127,345,278,230,300,164,351,367,325,191,350,230,0,153,11,354,0,174,148,362,123,309,220,334,1,339,244,273,352,297,114,335,2,301,180,29,106,143,55,271,35,263,296,321,92,227,329,332,284,91,386,129,175,327,321,294,37,109,301,0,111,301,246,212,110,0,269,76,0,199,398,2,244,314,14,5,5,166,391,378,196,296,296,304},
	{62,241,128,38,128,139,304,282,26,124,2,334,234,174,86,97,334,116,121,104,340,332,363,32,340,238,60,180,180,116,162,70,86,305,347,13,350,269,128,189,334,117,181,254,41,231,334,334,92,378,33,153,391,334,294,109,396,168,127,330,340,320,304,111,343,329,392,79,139,121,24,43,358,57,354,319,28,128,347,330,241,109,166,340,61,121,349,240,136,246,343,220,175,294,345,350,55,369,222,385,130,216,356,335,241,75,362,348,284,127,355,2,352,342,325,354,230,59,86,336,73,58,336,269,232,232,349,391,214,62,158,302,328,263,109,331,347,74,339,377,368,130,109,309,32,343,185,29,375,175,121,228,353,220,349,351,186,114,372,164,172,106,202,334,196,345,164,175,173,196,57,35,236,232,333,123,185,330,74,148,345,31,350,255,0,156,302,334,128,46,119,123,381,372,334,367,164,31,30,164,348,179,202,360,297,0,365,125,358,378,158,212,202,0,0,325,121,349,249,294,213,125,121,336,349,201,317,317,319,141,355,132,233,357,48,116,121,355,75,104,154,48,314,316,325,178,104,253,260,171,97,104,303,104,316,353},
	{104,349,122,240,354,107,355,178,251,354,247,104,44,325,355,251,148,240,355,355,344,317,316,316,317,177,121,348,119,176,176,316,344,316,313,283,240,175,150,344,359,340,91,384,329,102,232,348,62,297,297,373,385,58,242,331,278,152,32,241,212,196,92,124,375,375,8,343,348,246,186,137,261,319,80,82,12,304,140,118,393,145,14,337,158,131,92,150,62,337,125,304,164,6,329,82,383,238,226,305,154,250,304,385,320,88,237,63,98,208,303,232,132,346,0,5,175,249,198,143,96,342,6,62,34,171,378,84,116,375,44,156,173,173,175,5,0,228,193,337,68,92,110,404,47,37,162,87,349,115,72,371,84,101,220,74,74,102,29,346,349,78,96,355,65,335,144,279,285,75,19,63,114,344,149,55,138,58,139,108,203,3,337,332,355,9,239,11,348,349,107,340,383,246,94,2,83,80,252,352,137,331,62,181,159,135,36,278,246,372,169,169,240,36,117,21,284,343,104,132,347,209,62,354,21,344,251,299,232,374,323,134,178,374,146,279,68,56,304,3,23,315,13,332,375,74,348,375,348,229,92,384,241,272,134,208},
	{148,143,305,154,208,125,72,130,89,354,344,231,97,316,163,80,344,243,154,3,282,74,203,316,36,349,119,14,166,328,65,381,115,10,10,354,62,329,129,264,347,94,140,387,354,120,75,220,345,84,92,186,279,70,320,349,83,376,129,130,113,89,45,332,237,162,337,120,163,71,323,341,330,92,150,350,302,36,352,139,297,297,284,189,302,327,36,316,305,252,376,164,231,9,269,361,72,373,329,374,343,91,373,2,95,345,140,310,355,326,335,172,106,159,279,231,13,35,175,175,223,243,186,196,381,290,286,174,37,182,16,131,27,286,375,370,140,352,63,35,385,92,104,244,246,62,279,198,52,345,302,366,243,244,167,325,383,127,366,340,278,278,81,240,318,317,79,252,196,73,73,392,62,283,121,74,304,61,329,82,120,304,55,347,378,125,354,244,92,127,144,348,232,14,63,126,347,352,342,304,158,134,118,58,255,243,343,332,330,110,2,344,59,109,264,130,404,152,175,345,304,325,121,173,173,265,164,170,255,31,343,345,162,6,323,284,258,270,382,382,283,348,181,143,378,382,116,116,154,348,116,340,154,285,183,73},
	{285,348,68,350,40,126,227,11,368,15,299,253,171,84,54,331,341,335,203,331,153,330,322,355,323,297,74,375,347,247,0,96,96,241,188,188,349,123,35,55,363,310,303,84,136,220,346,12,90,284,306,303,315,345,14,348,149,124,74,0,152,357,335,6,76,166,119,309,345,228,135,241,200,83,335,82,63,346,153,388,119,241,139,367,12,348,126,306,361,12,330,120,81,64,343,145,63,5,281,327,303,5,329,5,126,166,74,357,126,284,82,123,14,176,74,405,217,313,200,243,125,302,133,218,29,109,332,79,92,293,263,81,324,114,382,84,180,57,258,353,131,345,129,326,376,224,70,92,145,376,220,130,357,191,232,37,356,382,215,345,201,336,82,14,354,320,83,355,80,329,354,102,70,20,208,377,385,371,55,208,355,315,341,375,75,186,196,241,14,282,245,75,110,340,78,374,193,8,198,84,171,386,386,284,254,332,346,182,129,97,294,337,325,386,134,278,236,258,220,68,126,286,92,87,333,123,135,128,96,160,125,125,348,209,375,373,92,332,113,101,343,149,345,194,169,229,344,353,345,29,332,349,309,321,251,386},
	{295,325,114,321,174,344,256,128,176,237,332,280,164,283,335,183,84,301,329,325,143,157,50,313,210,337,201,354,199,238,299,135,282,375,107,62,382,75,237,318,332,190,354,345,329,330,345,354,294,354,321,164,332,134,250,383,241,332,385,68,32,175,75,75,75,404,190,48,239,134,238,23,171,323,16,334,286,241,121,84,328,328,304,81,81,129,310,208,251,131,122,131,243,63,337,116,323,157,14,349,377,203,84,131,178,0,158,154,349,344,134,164,63,332,117,117,350,31,282,313,346,220,329,201,267,124,354,340,354,325,309,262,186,57,264,247,121,328,243,45,191,84,129,71,348,376,186,120,190,345,350,341,129,325,186,355,374,249,375,335,320,166,184,254,294,233,325,321,50,116,5,245,10,340,354,102,388,220,232,330,355,350,261,263,37,172,186,226,357,180,96,153,282,124,272,373,355,301,261,194,350,92,297,211,332,306,227,159,203,10,2,232,236,348,234,354,162,341,355,348,370,141,352,208,164,62,391,345,130,381,32,363,201,206,160,196,372,116,116,5,264,244,180,235,97,329,127,320,369,191,332,332,196,168,166,117},
	{102,61,375,340,348,117,330,153,220,330,345,31,128,186,84,79,345,348,111,128,84,284,14,278,299,244,166,341,336,211,68,348,24,2,210,214,180,311,39,130,47,354,236,261,263,208,345,303,350,243,211,356,350,190,14,196,282,337,208,70,172,355,158,345,290,171,128,255,158,332,350,290,335,251,189,164,176,345,378,158,386,129,136,136,146,357,386,386,53,300,84,11,386,334,336,188,294,303,10,92,97,217,342,353,381,106,176,343,203,192,48,323,286,31,344,386,348,84,386,164,342,20,263,200,212,212,350,176,10,214,261,302,102,368,248,354,285,3,316,295,323,262,220,114,348,131,384,189,378,58,114,387,100,377,66,323,348,10,284,284,38,282,143,341,284,353,119,348,311,330,332,95,36,253,95,334,359,367,284,106,345,334,124,282,35,261,120,189,147,151,18,339,23,360,92,355,92,349,189,147,249,110,373,125,84,214,19,119,186,246,107,354,284,214,130,214,375,354,10,151,214,246,196,29,404,98,246,116,329,168,375,214,368,282,325,335,151,121,168,137,119,348,348,10,246,173,10,83,53,72,294,343,59,404,72,285},
	{238,83,381,238,281,0,126,346,381,325,392,343,378,72,59,334,129,280,189,189,77,86,125,286,35,279,279,196,86,32,168,332,332,154,353,353,353,168,211,220,227,324,324,324,86,220,74,153,376,133,88,97,88,380,88,88,284,349,37,142,208,130,325,211,134,232,28,330,14,134,129,310,250,309,129,329,64,284,284,237,92,335,373,335,208,369,330,0,182,75,174,237,335,81,286,335,316,404,404,330,28,404,134,335,134,136,168,136,378,335,40,319,238,278,321,332,164,345,59,121,173,348,241,258,329,107,282,354,40,299,241,0,356,8,220,4,344,329,129,92,92,243,82,323,241,399,243,241,29,129,250,89,332,5,158,59,6,393,393,346,134,89,143,96,342,238,164,311,389,345,84,339,124,171,320,232,5,56,152,356,250,116,238,193,3,311,171,37,237,68,0,153,9,184,314,342,348,15,110,143,179,75,212,343,65,175,76,77,87,251,68,348,198,284,3,325,119,375,189,164,92,314,325,353,97,331,169,220,127,374,176,128,75,75,354,347,21,127,253,83,83,203,164,353,332,261,59,282,36,316,94,137,90,331,349,354},
	{202,140,160,157,345,252,146,38,38,302,170,117,134,157,241,193,154,154,389,97,52,344,344,89,178,178,171,136,74,374,104,349,68,107,374,325,334,232,345,295,129,13,389,148,68,369,97,349,386,363,120,354,322,346,83,249,346,309,348,375,284,359,220,75,378,369,404,345,186,107,92,92,119,313,283,186,243,329,354,387,158,143,345,345,325,387,29,301,261,143,246,354,309,174,316,72,330,327,25,305,350,129,139,172,329,295,127,386,325,13,63,54,243,352,212,54,92,284,267,295,387,126,168,141,31,65,399,66,316,174,370,369,369,5,26,250,244,391,391,59,59,330,354,232,173,333,374,20,246,128,345,160,369,170,168,168,246,61,74,392,127,136,220,128,220,136,369,348,342,203,347,347,348,212,345,92,335,143,330,62,5,391,325,348,261,59,171,129,354,356,349,263,129,169,330,173,173,63,350,330,134,31,350,325,345,325,203,251,33,51,176,63,63,212,345,345,345,203,345,42,150,42,377,120,337,343,33,33,169,95,393,127,134,95,0,329,240,240,29,249,249,92,348,294,6,375,371,333,348,130,300,251,0,343,130,238},
	{358,14,284,21,66,288,79,212,284,82,224,375,330,116,57,325,370,305,56,321,229,224,312,84,166,375,377,20,375,62,196,348,348,237,242,135,263,288,56,373,291,127,373,284,253,330,9,56,102,39,237,370,270,323,56,325,32,276,241,363,104,184,70,115,374,340,189,325,328,84,348,9,237,65,95,226,120,306,189,124,308,121,376,282,182,198,16,104,363,198,9,370,131,31,84,375,329,79,382,14,14,370,189,127,31,82,188,9,59,192,40,129,332,158,88,237,209,125,19,19,337,88,220,119,353,353,92,101,232,313,363,101,382,185,247,14,246,319,43,102,344,336,129,340,175,329,382,148,350,62,228,63,344,191,94,47,84,314,227,81,333,348,375,311,375,339,70,393,334,316,102,148,188,313,353,21,19,36,157,14,92,3,286,141,352,320,295,286,247,354,354,191,296,363,333,81,133,75,325,172,331,166,159,296,375,21,247,133,133,130,5,155,174,349,168,330,175,348,40,31,316,294,336,191,32,329,81,152,0,150,14,273,335,170,170,168,404,92,350,332,313,352,164,313,125,345,345,313,62,238,125,121,200,121,216,209},
	{139,15,348,241,216,82,250,345,348,361,14,348,348,77,270,284,77,284,284,95,64,349,116,84,114,329,318,37,126,6,282,62,370,370,306,84,62,189,332,116,33,217,131,373,348,189,251,323,280,267,355,131,64,370,126,244,231,57,244,14,14,281,304,125,96,91,78,14,147,125,17,334,304,104,244,114,208,104,323,136,343,92,102,58,175,175,317,121,375,121,121,348,348,348,348,356,356,270,337,326,314,345,345,354,37,23,16,64,18,231,352,234,370,350,37,37,385,348,92,227,376,348,324,34,14,62,171,84,324,374,50,324,131,56,330,343,112,346,118,404,115,324,374,375,340,131,316,48,375,157,48,60,225,330,0,92,32,375,387,377,157,354,335,129,125,309,331,233,120,84,343,325,227,220,325,330,374,234,309,60,375,375,17,60,376,34,220,121,128,121,186,173,333,10,250,336,286,14,348,161,258,59,313,87,92,258,258,31,304,307,318,107,348,303,53,375,324,183,330,79,350,310,326,326,376,38,329,92,329,330,129,353,323,48,295,150,354,15,375,284,52,35,303,384,246,209,122,338,215,324,332,336,141,116,139,82},
	{118,303,295,329,223,32,43,134,348,10,33,193,229,393,365,346,147,8,217,215,374,224,21,369,116,116,389,55,166,294,353,62,56,348,318,353,84,92,231,337,355,208,99,84,330,14,353,245,341,48,19,120,342,40,232,286,330,304,352,387,72,196,0,348,284,213,343,284,330,160,113,152,197,375,335,166,220,120,65,109,146,325,113,340,334,286,294,149,249,346,121,121,37,124,348,338,99,170,121,386,340,37,279,405,112,76,143,68,310,95,381,330,242,356,231,144,60,121,75,334,314,345,139,27,203,357,183,352,352,355,232,154,127,356,354,354,143,330,372,170,309,107,128,245,309,21,348,243,121,330,11,187,348,113,295,251,36,153,329,329,353,164,167,119,48,348,356,164,213,203,75,252,341,243,329,193,48,81,11,60,52,32,187,164,92,100,100,337,59,241,146,310,178,330,140,103,208,247,39,73,104,369,131,323,355,130,92,170,354,123,110,251,304,309,309,212,324,46,116,187,330,32,336,325,121,329,301,387,125,352,63,134,24,36,60,11,245,24,57,100,74,203,357,333,383,312,120,45,248,257,337,27,15,122,387,309},
	{127,39,11,341,325,91,243,325,354,354,14,341,119,193,14,348,190,352,241,305,349,75,336,184,242,143,354,2,245,345,264,88,357,387,294,163,82,350,153,153,252,114,357,297,297,241,220,295,120,92,97,134,43,208,335,139,374,352,26,343,282,20,330,355,335,122,352,346,164,272,306,349,47,340,243,303,120,357,282,194,95,281,48,234,198,198,104,37,24,24,24,52,193,307,370,314,5,290,182,100,252,362,133,121,139,166,223,295,246,349,404,279,325,317,182,332,281,352,247,141,62,375,404,135,241,241,354,237,168,295,353,38,375,314,36,241,250,231,11,17,248,128,366,37,166,237,153,121,127,374,349,349,330,330,57,304,74,72,319,297,136,27,334,79,82,160,160,38,107,241,332,193,131,168,329,24,136,50,332,304,283,232,348,40,332,216,57,304,131,295,107,128,325,341,68,246,246,134,272,144,335,350,5,184,348,170,273,137,118,187,158,2,170,347,155,331,37,354,349,56,188,208,188,72,241,196,332,187,39,375,221,221,40,346,20,375,152,152,353,84,172,192,36,121,31,188,158,118,341,255,31,92,134,119,281,348},
	{166,201,196,305,136,382,89,382,91,356,329,125,340,286,261,330,36,328,129,91,125,244,123,244,369,68,241,124,65,23,124,92,375,140,92,153,87,61,369,244,91,125,129,354,125,353,175,330,369,330,330,46,56,250,116,116,116,75,348,309,184,116,164,80,301,15,63,132,279,348,348,278,116,81,345,285,309,23,367,249,164,240,6,55,259,79,263,359,320,370,356,141,354,329,107,282,367,348,241,147,329,0,243,375,258,155,187,272,346,215,8,34,256,330,246,8,124,354,84,5,372,232,375,375,75,0,371,36,92,345,324,15,33,134,326,116,356,136,6,246,282,374,357,323,265,348,286,379,239,315,69,141,372,239,84,228,6,215,363,317,147,178,244,357,116,10,19,375,231,201,240,232,303,220,373,367,346,10,242,208,347,62,37,232,124,196,186,35,344,39,250,193,40,344,84,369,378,57,30,198,209,156,84,228,8,225,170,199,99,243,134,320,6,320,320,215,134,385,236,371,7,7,375,208,134,155,173,125,242,352,158,214,20,363,243,112,155,284,129,374,213,95,95,251,289,392,358,142,348,335,273,121,236,380,284,199},
	{7,37,98,375,155,74,74,375,245,3,216,373,110,128,149,68,263,311,169,367,175,281,321,136,169,134,375,176,344,328,302,124,203,58,128,374,92,121,332,354,2,345,221,54,20,94,309,373,36,301,301,243,186,216,134,231,125,348,313,345,299,323,335,367,83,148,329,137,249,314,154,123,316,385,239,404,6,107,280,212,135,363,296,354,385,21,323,375,392,380,368,175,296,345,160,300,9,125,119,59,325,323,246,231,281,169,193,187,84,7,134,59,328,2,251,356,387,310,44,129,316,12,199,209,328,393,331,241,332,36,63,272,178,247,89,74,285,64,239,62,370,122,92,306,242,241,225,286,323,171,347,344,136,374,167,98,348,340,345,374,177,23,304,34,19,129,309,146,318,345,54,388,134,310,243,144,7,285,129,175,104,194,94,375,57,188,31,272,100,231,355,221,125,374,353,243,354,345,153,201,341,262,232,325,269,388,341,191,309,212,29,284,387,373,348,343,352,15,346,119,345,390,3,340,344,328,242,41,92,309,156,156,35,139,133,133,316,129,122,93,68,334,65,335,355,243,347,367,367,11,220,325,0,158,329,246},
	{31,91,174,387,93,128,96,246,261,252,388,41,369,300,300,20,40,261,231,54,272,143,220,59,375,221,335,125,296,249,90,332,293,271,130,192,348,72,221,278,302,367,305,238,8,55,164,306,148,375,321,331,243,326,244,310,373,75,335,221,251,29,367,91,329,76,372,141,281,286,7,220,18,261,304,277,300,301,168,38,43,104,19,231,288,375,241,296,368,166,36,37,100,175,179,174,387,330,116,379,244,305,117,52,375,196,244,102,350,375,127,375,212,182,31,223,40,297,381,128,196,196,372,278,243,234,126,220,96,243,168,92,350,136,235,235,160,73,332,267,102,365,348,343,36,36,268,334,114,294,107,101,302,392,209,170,374,325,382,142,92,26,336,304,34,78,34,136,334,168,12,196,127,20,54,385,381,325,240,246,73,209,117,335,175,128,51,302,107,220,379,166,88,352,162,202,175,278,385,368,240,46,330,58,273,26,247,247,119,129,246,150,278,335,367,232,20,5,134,347,75,188,296,189,92,303,385,59,337,158,22,134,347,263,347,347,208,328,129,18,214,91,375,375,305,196,125,335,169,304,7,296,175,356,256,375},
	{226,346,162,268,286,51,209,332,229,123,164,157,119,350,179,173,243,243,360,243,158,332,350,186,255,278,350,51,335,372,179,186,196,37,390,176,304,390,277,63,321,305,128,136,158,179,202,375,102,102,241,343,238,79,285,142,353,87,348,95,107,8,80,374,238,63,147,193,329,97,110,27,334,189,285,104,62,340,128,193,35,133,373,74,354,37,5,7,340,128,74,166,212,14,32,63,252,348,88,270,143,345,73,241,315,334,74,128,131,346,331,193,286,378,127,2,374,62,373,84,286,168,250,338,348,128,278,128,385,348,166,14,303,334,334,326,342,241,241,368,18,136,368,0,81,8,8,158,354,158,325,69,283,168,124,116,335,124,354,373,128,328,315,69,130,37,375,84,244,369,250,385,369,71,385,294,336,385,385,246,170,385,40,71,378,80,129,108,354,284,229,353,0,227,241,369,184,404,229,232,172,84,80,341,131,131,208,389,371,348,172,280,125,0,348,241,375,79,234,79,369,150,299,354,329,92,92,92,123,260,57,133,375,362,335,311,343,340,86,156,88,107,350,62,340,31,284,152,346,284,324,193,193,384,45,329},
	{357,11,4,363,8,129,154,283,116,80,109,132,32,341,194,122,82,246,116,348,330,336,345,363,80,304,282,134,346,360,80,337,350,341,238,373,171,45,109,186,393,196,15,340,122,371,387,284,331,354,81,348,184,208,32,326,68,2,19,4,377,173,332,152,311,33,284,120,120,341,153,340,128,130,375,130,279,314,114,345,87,333,277,334,347,357,121,107,107,137,323,332,154,377,330,283,283,21,372,372,329,107,121,109,35,323,310,385,391,377,240,131,330,278,208,330,247,241,131,102,374,348,375,345,323,170,167,32,324,334,360,81,341,341,348,331,357,121,340,193,153,347,350,286,325,286,247,184,201,158,218,3,346,45,220,301,240,194,128,139,109,327,32,241,109,345,164,2,92,92,187,360,335,109,198,196,48,208,370,121,10,107,341,42,168,332,304,131,235,170,319,330,348,129,120,56,347,347,164,304,314,334,81,282,371,109,348,333,337,278,128,10,131,345,2,347,263,286,188,343,220,240,164,35,152,65,0,220,123,404,330,261,173,202,179,176,277,305,345,378,356,0,250,347,94,348,116,110,286,26,26,283,182,366,28,309},
	{391,243,340,155,349,245,82,232,356,353,264,231,82,84,171,148,250,0,405,311,293,373,159,159,391,194,324,324,319,33,241,241,350,387,324,314,159,160,188,173,198,0,325,196,12,367,286,286,0,378,258,6,240,74,74,311,164,249,92,133,14,339,373,47,276,263,358,251,243,354,88,329,29,278,343,79,329,386,164,337,23,53,258,280,372,74,370,183,37,348,91,95,70,375,241,286,89,311,126,278,323,157,133,183,346,180,191,375,355,108,81,11,129,68,90,220,332,40,45,224,286,117,336,215,378,39,295,8,295,92,356,130,96,92,184,232,232,324,4,80,82,348,84,201,330,116,347,378,336,373,220,170,265,75,186,371,104,375,48,357,391,283,286,362,74,164,175,125,36,295,244,83,201,334,373,148,237,303,330,375,99,334,124,124,96,84,196,348,347,347,284,212,14,320,348,171,19,208,156,110,226,79,376,56,47,350,84,7,197,88,241,254,262,286,280,295,372,331,353,282,102,320,367,254,214,352,62,375,389,29,57,97,240,133,5,84,125,84,393,143,200,378,17,172,30,367,294,378,229,284,99,29,220,36,133,284},
	{375,172,186,164,261,278,362,16,369,375,173,68,175,0,164,158,352,286,343,289,241,373,241,164,348,333,373,164,273,155,140,19,258,334,7,258,19,386,39,348,47,340,378,392,391,77,77,354,78,95,142,160,369,164,349,346,110,93,375,284,91,359,176,84,129,113,102,306,101,325,152,263,3,3,135,348,385,148,375,248,314,271,271,119,134,133,342,74,44,354,360,0,350,129,172,369,344,256,373,58,241,127,117,102,126,382,343,301,268,373,11,350,155,131,238,12,84,265,314,136,330,159,172,83,241,326,137,107,349,167,249,313,353,186,9,173,231,382,62,342,316,362,353,97,14,62,107,386,375,258,11,94,332,119,323,221,124,311,92,334,404,151,280,399,82,295,188,329,164,294,69,246,350,301,134,309,335,154,385,286,31,79,325,131,164,19,331,0,306,375,157,166,125,385,171,164,241,19,178,295,243,190,241,241,23,103,31,372,81,229,9,239,122,387,36,362,92,169,231,354,354,97,103,68,305,89,324,62,54,79,36,369,241,355,345,354,251,348,274,282,44,163,330,385,297,143,157,388,388,371,100,82,82,35,247,212},
	{323,104,175,109,245,348,377,134,134,36,393,167,244,375,383,344,134,232,128,385,386,18,231,66,40,32,187,117,125,102,330,70,243,59,102,63,179,375,251,0,84,94,231,278,348,320,282,74,347,84,325,325,71,124,387,125,348,282,330,345,345,42,369,45,354,110,367,328,233,14,220,149,340,267,346,156,345,12,121,153,129,153,294,83,335,320,375,125,198,184,40,148,116,166,163,313,201,354,353,186,295,355,341,346,373,233,347,92,242,347,40,292,354,49,325,186,309,92,129,139,249,350,262,120,174,161,251,333,236,284,87,304,158,357,354,35,404,134,282,40,232,335,124,348,373,84,221,189,159,261,97,130,134,302,220,373,9,335,355,386,194,297,124,220,129,120,107,81,367,243,180,300,355,335,261,284,375,52,326,313,172,261,305,252,368,294,283,302,143,330,97,241,142,90,300,226,306,91,45,373,400,92,293,129,44,244,29,332,118,186,340,89,90,385,320,127,346,63,124,140,375,59,173,18,378,271,330,92,166,121,352,243,104,87,87,317,117,241,282,391,231,353,116,126,116,119,102,348,348,90,141,102,102,26,323,130},
	{375,382,357,159,35,387,164,339,247,290,79,314,100,363,297,162,175,167,189,404,128,297,143,40,305,16,175,168,372,367,286,370,182,196,211,346,311,231,378,276,330,251,113,125,48,92,345,244,342,350,375,343,375,127,391,48,240,286,117,153,373,392,356,278,330,45,63,81,88,196,329,127,256,170,172,127,332,266,79,369,320,160,357,292,318,36,305,188,134,36,334,136,136,336,121,92,221,333,320,214,265,378,314,366,82,248,345,113,246,97,172,160,90,40,330,283,386,270,92,69,131,175,125,40,355,55,286,126,304,170,203,349,330,121,278,391,341,36,88,134,391,348,246,240,345,162,83,121,58,92,299,20,237,36,40,379,121,92,129,124,247,368,125,244,59,348,16,295,281,170,164,29,188,349,306,303,190,241,317,19,123,92,243,208,214,348,90,140,349,264,247,345,241,189,371,102,45,92,153,238,61,40,91,190,353,375,120,243,162,169,268,175,164,51,404,192,121,223,404,375,90,70,355,356,81,385,296,166,126,40,247,378,404,345,164,378,246,129,75,297,118,212,354,173,157,128,332,0,134,339,171,350,278,349,353,350},
	{333,216,20,369,166,134,290,281,391,48,251,250,25,0,354,179,164,390,176,305,136,345,158,158,378,179,164,6,202,354,171,101,243,47,119,336,354,348,332,223,340,33,330,241,143,349,136,330,340,331,354,153,159,336,296,330,335,348,241,340,41,349,151,243,336,243,42,276,98,349,336,335,354,243,334,347,91,346,304,253,223,116,334,119,340,230,348,334,340,330,0,166,40,348,75,354,46,119,375,374,47,21,329,241,21,21,322,134,243,375,273,37,273,376,301,299,164,363,354,164,153,56,75,294,125,372,326,196,220,196,50,346,310,283,56,279,340,343,286,24,136,234,242,249,297,247,357,166,348,347,375,347,24,187,57,92,65,373,357,326,39,18,309,130,279,349,64,133,153,51,348,57,70,126,166,18,70,125,125,286,223,71,378,349,283,348,335,252,127,220,343,63,121,121,97,252,241,348,250,121,71,348,334,329,100,198,186,186,2,129,70,354,14,14,14,232,232,14,31,184,0,0,232,169,124,369,269,198,320,343,77,261,332,134,198,109,249,221,0,304,229,134,74,52,14,270,270,184,299,286,286,320,143,125,302,270},
	{286,198,184,314,261,32,240,175,369,272,369,188,175,250,65,284,62,193,136,183,241,235,200,241,59,332,42,82,346,205,18,84,282,68,247,330,349,330,106,346,3,344,143,247,344,68,57,404,247,346,357,357,291,270,374,19,352,58,291,161,208,319,79,249,313,375,249,224,363,190,51,121,64,107,29,385,42,323,79,56,330,320,183,353,241,278,236,107,243,354,354,343,294,263,95,126,37,329,316,133,305,375,375,243,189,97,324,131,131,319,137,114,303,251,92,15,15,107,326,376,227,338,342,120,353,241,82,340,340,246,348,328,357,355,108,345,282,35,57,353,73,116,123,241,198,405,196,302,190,329,38,227,14,276,375,229,226,386,358,96,172,186,363,83,223,164,178,25,83,325,116,196,186,286,134,358,320,320,74,110,373,373,348,78,81,353,310,375,371,97,369,345,294,152,350,134,335,249,348,124,376,251,20,121,189,12,363,378,161,353,97,114,88,78,184,294,116,237,386,79,375,297,214,36,171,228,20,241,294,208,134,342,378,283,162,341,342,84,226,193,303,346,92,352,100,13,342,173,175,57,179,335,238,363,131,349},
	{377,129,347,121,121,359,36,349,325,115,125,346,169,294,92,77,337,84,268,386,375,349,329,330,142,378,126,179,0,345,68,309,197,162,348,189,251,130,238,325,334,348,114,340,297,152,306,245,134,77,377,263,237,343,338,375,120,119,194,123,321,242,225,329,250,172,348,124,131,243,126,128,373,284,385,27,0,121,92,172,31,122,116,216,343,130,169,249,325,372,137,107,9,183,385,353,330,20,69,119,114,348,240,374,158,109,159,107,164,94,84,329,166,45,114,348,354,314,160,106,130,331,38,132,186,299,36,229,332,282,316,154,237,212,107,247,334,281,258,316,352,334,332,313,75,297,357,135,399,309,164,291,294,162,291,306,70,160,157,166,325,328,357,119,62,113,266,125,370,273,84,100,337,306,289,344,46,370,347,202,355,107,320,68,110,328,134,281,167,122,302,385,63,245,60,135,386,330,334,241,116,104,345,170,305,377,231,109,32,286,243,80,37,175,203,134,306,48,164,372,237,81,295,310,232,57,354,208,354,175,88,189,131,171,178,349,52,250,118,354,282,282,116,45,116,355,157,122,247,345,243,310,191,375,349,238},
	{12,355,326,267,81,247,355,143,241,281,355,273,175,386,70,241,125,190,232,330,354,355,282,282,262,119,378,125,218,354,329,313,250,70,83,367,20,328,328,309,325,326,264,335,27,325,110,89,345,114,341,189,143,184,350,345,353,247,191,283,186,359,122,200,102,37,75,225,186,166,241,241,186,310,49,325,24,317,190,193,238,340,92,230,125,125,116,83,333,348,349,369,284,335,374,120,304,354,14,193,284,316,283,352,134,314,317,249,249,249,345,346,173,123,355,201,226,353,251,382,167,31,345,384,110,386,323,284,187,350,156,153,83,125,340,174,325,87,331,350,238,130,345,305,355,301,355,332,220,188,385,36,143,303,302,321,172,147,272,194,367,284,348,178,180,240,325,164,359,329,330,326,244,363,284,297,2,246,296,357,339,349,261,122,297,301,208,302,284,263,2,226,340,40,227,327,25,192,91,63,342,120,335,386,62,375,350,84,129,117,91,386,306,308,299,14,128,121,103,349,363,290,375,345,281,182,350,45,404,158,176,334,18,304,354,339,116,14,16,375,126,147,282,279,62,189,5,175,340,116,353,31,79,352,103,187},
	{247,354,234,92,344,33,241,330,92,175,175,173,130,104,295,174,375,87,244,164,345,26,128,48,45,381,223,308,347,330,189,305,196,305,304,166,158,321,303,88,231,341,348,182,386,183,141,179,231,286,370,370,382,340,119,155,243,345,290,334,52,309,346,126,387,350,114,336,286,119,350,334,387,154,340,166,375,325,235,286,127,238,346,121,129,329,224,92,226,325,334,243,243,344,175,330,300,73,120,193,266,297,168,373,387,348,375,323,304,304,33,349,335,347,280,367,378,270,111,14,278,31,31,286,314,240,170,325,273,273,36,132,36,117,203,160,34,88,53,114,294,286,231,107,357,172,114,84,109,110,332,125,278,330,354,175,158,214,354,170,283,362,58,119,363,335,354,164,284,342,171,323,386,352,150,24,166,63,347,5,341,373,31,182,57,57,348,299,232,134,302,246,92,385,166,216,328,246,230,273,276,299,325,40,302,295,313,273,378,157,18,166,208,330,286,189,214,350,350,188,130,241,14,241,109,263,391,328,306,349,349,72,47,123,247,158,343,143,240,385,325,18,97,243,350,18,155,81,25,185,360,325,238,360,175,164},
	{353,346,175,294,375,350,70,324,121,335,226,282,16,31,196,172,125,10,273,36,97,18,123,332,175,246,107,350,261,164,131,334,350,299,325,335,322,342,378,290,157,72,79,116,157,286,171,350,208,92,166,392,350,82,170,348,125,356,31,56,255,125,158,79,290,355,385,83,281,162,158,48,250,352,243,78,100,136,345,109,350,332,360,176,345,164,189,278,304,58,128,31,350,109,6,378,158,158,202,323,176,343,332,345,88,345,354,123,294,192,101,61,121,334,334,121,114,171,362,381,133,367,335,37,385,359,359,24,346,241,376,82,215,102,326,240,348,175,44,232,139,226,345,345,227,198,33,168,252,141,73,101,336,375,101,101,325,244,15,55,331,374,378,143,371,84,6,335,335,171,385,341,134,304,228,132,228,303,303,19,346,314,278,378,367,63,325,284,166,37,120,377,116,293,158,313,220,340,113,251,169,119,346,339,339,332,349,344,377,220,284,325,314,342,359,139,114,160,331,378,341,374,238,345,121,101,34,121,142,35,79,280,347,121,0,305,130,257,169,330,84,132,335,240,313,385,313,323,106,231,159,345,340,83,37,261},
	{116,330,286,123,343,148,356,334,330,345,107,382,250,62,335,241,329,0,404,107,345,119,187,134,306,11,82,170,154,122,319,330,52,329,114,134,84,328,128,48,83,237,248,267,348,248,336,33,345,345,348,127,354,89,254,232,350,324,283,98,280,0,0,94,325,35,110,153,376,71,331,357,83,166,341,337,120,128,125,14,350,378,325,317,278,330,341,218,31,345,132,132,354,186,276,325,367,130,248,262,186,119,340,371,325,79,249,299,346,169,378,129,362,98,10,116,357,201,284,167,15,96,318,305,33,278,357,20,347,335,330,329,330,357,110,334,348,357,338,200,278,248,220,343,189,243,350,329,261,95,345,244,172,330,14,16,387,175,125,286,348,174,231,299,348,314,136,387,357,116,348,375,5,325,172,254,223,257,132,182,154,279,51,366,125,330,330,330,348,334,37,120,57,347,343,254,345,343,334,137,61,319,282,127,82,330,168,354,170,314,280,82,79,345,343,158,186,305,348,132,187,131,0,350,354,348,342,158,303,362,24,299,330,252,387,243,121,378,335,171,354,348,335,371,121,55,0,19,264,332,334,343,130,39,306,220},
	{110,158,16,261,169,196,10,267,404,169,5,343,152,356,168,164,175,136,168,345,330,335,173,347,24,255,356,158,48,136,314,100,134,34,189,305,158,378,158,171,51,354,371,371,224,374,228,36,355,2,325,107,136,136,84,347,6,65,347,220,389,290,189,226,43,143,361,65,244,352,244,233,8,226,33,125,225,70,43,354,367,190,65,226,20,43,353,353,70,344,36,215,215,236,161,197,320,198,160,258,183,80,184,198,89,329,345,361,11,294,125,97,353,91,283,198,368,243,251,251,386,307,330,183,145,243,329,97,330,164,164,239,92,89,375,12,251,45,70,134,124,125,83,233,143,134,142,40,330,11,179,129,180,270,325,184,73,314,127,126,330,164,70,169,225,234,20,330,39,325,256,39,251,79,6,79,249,92,30,385,3,110,382,101,180,353,141,229,115,344,349,119,382,357,152,215,62,152,376,198,11,232,134,348,337,228,331,348,116,171,81,232,208,220,353,96,342,134,57,20,148,332,214,341,112,128,196,371,129,343,278,302,261,285,314,160,70,331,284,150,374,354,300,354,14,385,330,135,164,331,349,298,159,11,375,345},
	{276,164,107,332,131,225,81,334,232,241,208,16,349,157,169,125,244,154,345,104,387,189,32,348,375,374,344,188,23,50,281,169,0,179,116,387,0,325,83,328,355,337,378,184,325,278,332,317,344,203,335,124,115,233,353,353,186,29,220,300,238,194,117,355,296,180,355,56,354,284,109,244,348,373,25,109,182,131,126,198,370,31,5,5,90,52,82,136,14,14,120,240,170,354,382,220,168,330,334,285,0,128,91,341,70,121,150,332,335,302,332,343,214,15,123,263,188,169,353,131,285,175,302,332,189,255,119,203,179,332,241,136,341,220,386,404,175,354,297,324,249,86,66,161,6,92,114,62,42,88,133,354,241,354,32,180,114,329,84,193,129,344,18,187,9,356,136,357,136,323,349,186,57,236,325,119,332,244,171,56,348,88,237,63,84,341,330,20,49,96,124,280,238,47,143,254,283,282,348,389,124,193,278,172,14,373,373,136,78,173,130,128,125,164,101,332,377,95,345,339,346,340,179,297,378,246,349,343,10,77,333,220,331,113,102,38,340,8,229,160,58,350,121,326,75,313,309,329,329,36,137,186,11,313,332,40},
	{107,341,345,249,341,159,164,339,84,172,344,330,171,164,130,166,301,301,83,323,63,236,369,273,193,354,134,35,157,193,324,354,310,40,385,229,36,116,241,75,154,32,241,13,323,175,48,251,345,64,229,170,246,232,224,244,385,246,78,130,248,70,129,122,354,184,186,45,341,309,337,56,262,193,125,325,264,119,335,42,125,381,346,166,251,331,71,355,344,203,116,350,354,120,265,273,172,284,261,301,220,326,329,373,130,350,180,306,172,305,164,159,102,310,244,54,136,371,220,2,18,316,32,154,381,48,130,348,52,48,241,164,131,362,249,341,5,166,187,370,349,117,350,325,175,329,61,339,366,343,250,58,170,168,248,297,120,102,240,131,79,130,172,92,121,131,2,14,24,250,362,58,128,103,304,150,119,273,299,310,40,354,130,175,233,286,326,391,158,330,386,341,264,328,87,162,70,164,375,262,164,360,341,309,102,299,156,173,175,164,360,158,350,330,333,325,100,59,360,347,98,20,65,228,116,375,234,8,255,164,321,0,333,0,8,230,80,57,327,223,0,0,321,116,171,348,237,47,0,135,32,37,0,58,188,21},
	{383,237,15,377,373,0,47,350,241,332,174,62,223,188,381,13,170,366,329,232,57,327,350,345,88,56,282,310,310,107,32,283,247,282,31,31,265,283,297,282,352,288,175,84,352,13,83,214,310,353,124,282,367,63,84,201,63,237,66,117,66,384,359,188,14,14,172,300,172,32,198,357,79,84,94,310,129,129,251,325,84,310,198,0,226,126,321,84,201,172,12,373,40,198,198,92,310,87,14,55,375,177,241,177,226,348,79,117,354,354,198,137,348,172,281,65,39,117,58,383,92,323,126,36,32,319,162,92,29,172,65,317,170,126,126,39,232,65,65,286,245,57,286,286,375,348,19,200,66,14,129,168,89,91,133,377,331,278,340,219,164,346,35,353,6,129,342,241,344,52,14,348,164,387,43,83,378,228,232,88,143,47,342,375,57,373,78,375,308,134,92,81,134,278,124,341,367,19,212,374,352,131,251,308,314,348,129,354,121,304,346,37,375,112,344,186,69,131,334,314,316,183,232,334,298,240,164,375,54,74,329,276,160,285,119,332,348,231,370,100,304,81,180,170,37,92,310,347,37,14,232,193,97,72,143,325},
	{354,52,344,378,50,57,282,376,375,354,115,83,156,346,35,316,354,104,326,119,148,124,349,348,174,272,136,37,330,100,348,326,92,43,8,162,172,54,285,0,63,55,17,304,370,16,282,50,179,348,387,39,370,368,296,273,252,64,174,404,196,246,349,350,120,84,293,173,127,172,160,332,81,304,349,110,2,8,332,100,325,216,354,325,348,352,232,162,164,286,57,170,63,170,157,17,92,37,346,341,129,374,185,164,123,157,92,63,341,350,349,250,352,304,63,179,176,176,20,0,102,6,78,61,78,7,7,245,92,362,362,184,60,224,129,120,102,47,171,90,196,92,128,231,90,2,75,109,107,14,323,39,243,330,2,334,109,120,109,363,52,109,334,347,238,109,128,2,337,120,179,234,110,128,232,88,228,377,137,249,53,252,367,97,137,137,377,367,0,371,70,193,241,350,354,11,371,376,230,110,350,110,348,20,323,110,4,369,345,125,110,354,153,79,87,59,226,84,249,283,59,175,369,188,164,130,340,140,341,100,3,404,340,377,58,3,97,164,198,66,88,340,183,324,375,241,355,332,333,73,336,330,226,83,73,193},
	{194,283,284,357,190,226,80,191,57,186,186,140,332,147,284,350,374,220,282,123,55,373,152,340,282,348,283,186,196,378,373,373,190,284,355,65,208,386,386,33,367,341,80,226,173,299,314,189,375,62,204,194,343,37,152,135,197,373,311,346,345,196,376,196,372,374,186,301,334,107,119,62,36,380,135,75,182,332,330,154,157,125,278,310,178,323,163,284,248,169,344,131,374,164,157,391,135,291,299,70,232,232,198,122,208,175,363,129,23,377,354,122,180,331,337,121,103,359,45,125,186,70,115,341,310,153,90,265,184,340,78,328,191,39,102,189,327,147,58,310,143,296,331,248,196,194,182,82,363,370,348,69,147,196,292,48,404,37,187,234,36,102,188,119,292,235,330,127,240,378,61,282,292,168,34,332,140,347,342,314,329,170,325,125,347,2,121,369,125,97,371,250,186,39,272,214,343,220,356,188,190,236,190,162,152,136,341,190,123,175,188,173,251,182,330,40,305,140,378,184,130,246,354,293,385,136,284,348,282,375,115,282,350,134,377,128,54,71,2,128,366,356,6,284,66,241,92,386,88,329,372,242,244,330,79,152},
	{58,180,276,57,136,164,84,326,75,117,141,375,241,140,129,236,75,344,232,372,345,299,381,34,73,321,345,130,83,78,196,367,389,354,179,320,320,62,368,373,75,84,198,378,156,15,217,237,231,171,240,161,238,75,238,282,358,2,164,173,314,352,164,152,40,145,251,378,152,102,75,203,242,175,325,2,91,349,337,345,68,237,330,160,114,293,331,127,247,325,127,0,247,334,252,31,159,114,354,334,331,183,179,352,34,34,328,172,350,183,252,345,276,154,97,0,117,175,35,125,219,295,385,145,231,345,383,146,36,241,387,247,170,137,226,66,193,64,369,110,175,2,299,330,163,11,349,72,329,241,178,323,63,203,11,241,35,264,345,65,66,377,320,129,350,15,143,14,325,293,373,71,331,58,309,203,231,125,62,304,29,310,241,73,83,341,252,252,180,95,209,335,75,47,172,309,305,9,143,232,325,271,162,54,310,344,241,166,226,325,357,383,372,143,156,0,220,103,381,31,241,127,231,172,175,140,43,35,349,162,234,241,196,378,52,387,247,46,178,92,278,160,250,366,61,125,330,170,66,63,120,226,358,127,62,164},
	{125,128,330,370,127,73,332,354,383,127,143,363,162,129,40,347,252,58,348,126,232,232,354,236,241,348,143,125,354,264,188,228,47,20,346,180,22,336,152,162,162,375,164,179,79,252,228,350,164,173,173,196,20,290,100,158,22,345,284,284,164,259,281,356,294,241,302,180,335,220,332,375,241,375,80,72,376,0,348,284,353,375,311,84,84,189,389,375,298,186,393,250,116,378,282,299,47,30,189,404,354,333,329,311,234,378,102,331,375,92,90,373,90,291,130,282,87,154,62,59,123,306,241,97,100,391,171,175,19,130,59,375,175,31,14,40,121,353,330,349,386,123,373,84,355,329,332,346,375,348,186,294,62,11,385,373,352,92,90,305,294,180,302,84,341,241,354,330,241,294,304,57,102,299,164,216,332,59,164,255,356,375,360,162,262,354,354,164,335,246,110,316,339,294,258,316,386,199,88,375,332,19,209,249,249,376,82,184,357,143,191,375,131,14,375,354,189,148,8,232,208,164,353,389,232,20,171,196,36,209,246,346,393,375,375,286,134,386,123,92,36,314,375,155,110,349,386,375,129,258,70,348,378,121,216,240},
	{330,90,159,84,363,320,404,154,88,131,309,36,316,280,291,344,178,175,97,393,258,384,9,7,241,375,375,154,163,231,143,170,39,391,354,297,297,0,348,330,15,92,84,232,221,129,376,387,340,36,59,326,332,386,354,92,340,373,375,59,124,92,142,90,97,261,299,261,92,141,198,278,189,375,92,175,297,92,350,326,249,273,0,348,120,245,92,299,334,240,128,385,376,391,404,299,216,273,121,255,221,354,236,386,318,326,36,123,152,404,228,273,255,385,164,360,342,344,133,248,330,248,146,354,282,131,220,42,384,316,160,245,368,220,15,10,220,19,321,378,228,127,64,329,321,220,375,43,220,311,128,43,132,334,36,147,51,328,57,148,143,385,340,297,100,153,69,385,343,328,321,347,354,134,248,220,220,311,33,354,310,64,174,168,330,329,153,43,371,151,151,173,36,52,168,362,51,127,248,70,362,173,245,164,40,284,84,243,40,114,241,109,283,82,286,191,250,369,378,171,207,19,131,131,370,7,294,137,114,314,295,373,64,348,286,131,250,129,237,71,164,381,28,61,53,322,131,140,131,378,378,161,231,354,37,88},
	{183,378,323,70,92,128,6,298,92,246,371,300,344,383,355,116,108,334,130,232,14,125,348,68,278,283,331,62,378,199,37,97,164,245,193,10,311,294,84,278,12,229,55,386,62,171,363,217,84,96,79,124,88,79,284,184,238,334,125,248,173,193,15,179,102,250,37,349,220,332,14,248,155,61,128,130,251,357,263,78,152,378,314,92,55,108,27,376,147,157,14,277,58,374,27,84,137,316,224,164,159,134,100,332,107,352,331,375,36,298,284,378,393,334,280,313,124,345,90,150,88,39,152,89,357,222,243,334,125,240,157,388,225,14,232,91,303,99,354,125,371,97,116,374,247,367,377,175,20,92,170,298,253,84,367,97,146,243,243,137,383,100,355,27,389,20,363,245,320,179,57,334,267,125,341,15,300,333,332,237,373,337,116,348,378,356,45,404,329,68,334,92,129,120,337,186,79,71,381,233,83,378,114,245,115,249,191,243,97,153,284,174,357,110,305,356,39,90,81,267,374,96,212,243,334,51,173,231,70,164,14,385,40,284,37,378,244,173,158,125,21,164,121,14,378,48,345,231,360,390,232,234,69,354,192,381},
	{368,277,104,348,116,31,147,50,237,362,92,102,297,404,92,175,209,301,51,64,301,161,71,167,334,20,189,294,305,168,57,63,84,125,193,153,56,128,61,120,381,160,360,334,175,284,360,241,225,241,232,88,134,175,175,345,20,58,269,379,96,243,166,21,377,157,284,158,153,354,356,109,373,303,309,212,306,92,348,241,308,381,377,226,296,377,243,385,308,175,175,125,320,350,354,157,173,245,166,158,243,356,376,250,166,15,71,390,164,284,179,350,356,385,354,189,62,79,282,372,282,405,110,162,332,386,208,53,370,243,368,232,8,329,276,141,262,82,14,299,349,372,189,303,116,6,164,88,134,238,196,50,369,377,164,297,311,164,330,297,114,314,47,273,356,377,170,382,7,160,82,77,250,110,167,332,84,167,24,131,164,356,175,134,241,52,7,370,170,387,131,117,117,270,270,305,15,262,190,115,340,387,116,125,360,47,164,335,84,221,11,97,339,90,305,249,124,26,382,305,189,270,82,362,141,126,196,270,270,221,330,167,126,150,20,119,286,92,332,221,317,212,164,393,62,212,311,158,189,294,133,330,95,374,133,353},
	{92,29,377,343,356,126,354,129,323,258,326,326,249,199,386,315,215,85,129,286,384,232,373,276,114,375,92,82,357,258,57,130,297,80,301,389,133,367,6,130,84,375,241,386,377,114,367,162,330,84,348,282,20,378,250,171,378,280,88,346,84,320,373,56,40,284,376,341,389,132,8,250,196,286,391,152,131,258,108,348,129,378,39,149,196,136,152,116,47,119,94,306,335,148,334,251,87,179,343,231,332,84,331,314,261,311,349,162,335,135,340,106,65,314,294,126,333,121,136,375,125,341,375,326,373,404,36,249,286,9,314,334,323,332,94,339,309,339,335,114,330,84,313,299,72,154,84,131,116,375,345,132,83,92,340,258,387,282,74,169,404,167,306,251,280,241,241,384,241,323,374,332,285,348,241,306,323,89,324,13,383,23,104,389,178,172,348,369,14,46,171,190,241,245,310,387,122,388,330,386,337,167,130,81,265,193,354,387,79,404,340,350,279,241,340,333,125,143,332,264,190,241,71,376,62,193,191,355,347,10,294,249,15,119,94,387,190,325,84,325,340,96,191,335,166,387,233,357,349,309,98,375,357,36,31,56},
	{331,355,387,340,350,325,94,0,350,130,348,383,208,9,116,226,377,125,301,251,290,357,331,299,330,261,306,84,357,373,90,263,116,366,308,341,297,373,387,306,120,23,14,83,50,164,301,349,330,387,162,381,243,182,375,404,198,234,166,189,341,387,92,334,299,79,404,13,348,362,198,220,244,122,332,92,276,339,254,341,299,127,366,393,375,278,270,170,354,79,256,46,392,125,256,31,265,339,121,117,390,330,244,357,55,350,121,330,273,125,126,119,362,48,335,385,14,304,348,216,299,348,277,340,92,18,243,158,240,343,390,241,231,220,196,162,335,390,152,353,340,162,332,31,128,175,31,350,278,333,332,391,390,179,330,59,158,162,166,128,133,354,114,377,332,91,356,92,323,152,92,258,325,357,114,45,232,276,89,199,258,387,178,82,375,326,80,378,373,215,286,332,88,335,84,166,389,282,330,375,376,377,8,84,40,280,348,131,56,9,261,129,148,256,65,108,121,0,341,126,179,136,128,314,94,334,135,339,330,299,306,92,309,92,340,171,350,340,241,81,33,279,103,283,325,190,285,13,39,306,172,251,387,369,323,404},
	{383,386,143,333,125,190,158,309,191,92,357,121,294,74,71,15,332,96,383,119,62,404,15,193,355,130,84,263,373,83,299,90,31,164,348,125,18,234,182,162,350,301,195,272,335,168,278,366,126,243,127,119,128,390,85,335,89,85,252,85,241,20,237,333,371,89,350,350,247,331,100,392,304,25,241,327,350,162,304,175,100,324,294,89,324,107,0,179,84,282,78,97,378,134,188,97,193,89,6,98,309,135,84,282,345,371,391,99,385,354,375,3,78,158,286,294,232,180,172,232,78,164,33,325,14,92,366,38,172,92,135,189,371,179,232,92,92,176,346,189,244,55,186,346,353,353,82,6,90,346,97,353,361,186,171,348,378,62,339,244,348,332,261,253,253,244,119,301,348,348,346,244,332,354,159,129,305,355,330,79,278,82,278,166,162,94,400,244,31,354,114,348,38,327,82,114,37,37,52,84,331,230,348,156,348,238,171,175,375,354,330,335,333,330,330,143,127,121,121,334,276,114,126,368,52,81,377,276,37,378,125,341,37,233,387,323,121,115,110,110,107,5,234,348,166,250,5,170,230,127,5,79,348,121,341,59},
	{220,160,0,142,184,372,241,96,96,96,65,65,77,287,264,200,200,381,162,313,386,94,33,109,357,224,232,348,294,250,124,134,123,40,160,178,129,305,223,174,400,126,227,367,174,92,160,123,353,196,118,77,348,66,347,55,295,246,357,37,57,57,114,94,375,0,212,57,373,34,171,374,353,385,168,173,375,214,311,405,344,372,104,0,166,109,283,169,236,131,134,14,62,104,326,340,237,48,66,0,313,134,48,153,166,153,48,166,327,153,166,166,48,5,283,295,313,153,372,375,57,214,245,208,313,313,173,354,354,371,294,297,348,297,294,371,371,262,348,162,92,249,144,26,241,62,119,120,37,258,334,263,377,355,70,89,261,88,29,328,32,97,375,246,84,81,82,229,227,125,80,384,353,199,4,144,254,95,354,326,220,241,232,243,330,330,81,144,131,303,282,376,370,335,282,325,377,65,57,81,6,20,340,310,11,98,303,386,148,375,208,237,386,377,227,373,332,393,229,124,283,375,10,198,250,116,143,37,349,340,346,173,68,138,175,131,217,345,227,149,348,101,106,91,68,375,128,338,338,77,3,113,233,207,386,153},
	{374,311,375,52,186,335,52,335,181,181,92,335,213,150,268,361,241,203,189,216,176,326,20,326,323,339,128,145,353,113,54,228,278,313,186,45,282,250,307,391,92,353,336,320,228,36,318,240,69,320,211,203,232,97,179,164,166,370,299,129,167,291,232,16,178,233,162,251,115,57,310,205,131,200,156,347,345,258,282,383,84,84,134,81,244,323,68,232,123,387,66,328,186,264,381,37,49,179,223,62,3,337,203,286,289,201,357,376,262,75,269,316,220,125,325,136,354,124,71,14,32,84,332,208,190,321,308,318,9,345,404,321,285,305,297,383,91,348,20,168,92,232,335,90,404,18,223,32,175,123,227,41,16,126,175,305,196,330,381,175,128,350,404,375,342,399,170,314,231,208,41,168,52,153,334,319,226,375,128,278,329,52,0,333,0,82,350,278,379,57,150,216,319,166,14,352,136,40,348,135,156,166,272,319,97,241,52,18,343,263,356,361,332,16,337,154,169,345,175,123,358,179,250,361,176,208,360,35,332,328,132,361,170,132,386,128,212,39,92,109,339,190,212,375,375,91,125,375,375,339,303,373,133,332,354,29},
	{220,354,38,330,330,133,354,354,337,134,133,336,281,281,281,133,284,310,286,284,310,304,240,240,100,241,310,42,292,331,329,377,59,42,278,348,79,224,303,79,8,79,108,80,8,14,175,376,125,25,171,378,363,74,20,332,91,42,331,175,248,227,330,149,84,362,83,164,280,354,159,313,0,325,20,188,243,0,120,285,387,15,198,65,69,9,29,348,296,25,26,174,56,342,220,38,61,58,244,175,348,92,125,328,188,241,175,175,31,290,93,167,125,125,273,345,84,237,345,345,26,26,348,161,313,128,2,200,311,128,129,231,323,348,29,190,189,88,243,354,354,280,338,70,331,241,183,386,121,299,375,333,232,84,319,325,329,375,241,278,326,243,258,84,147,129,175,378,92,246,241,355,82,6,265,336,92,117,117,80,329,136,92,375,357,246,5,388,184,344,81,259,108,48,349,353,15,348,245,325,164,232,75,332,32,25,378,297,309,355,254,171,303,311,62,191,247,164,352,143,198,11,10,96,193,348,348,134,235,267,148,378,208,224,19,278,339,220,332,12,114,350,393,68,134,65,212,88,116,237,186,84,283,98,189,325},
	{84,385,184,79,245,184,184,6,47,196,386,375,37,92,131,173,48,211,0,342,350,248,179,194,164,261,349,93,243,375,35,354,339,386,169,329,92,102,47,125,47,96,101,183,29,128,211,84,354,378,386,126,121,349,29,229,261,263,38,198,314,376,243,378,343,119,84,251,87,302,131,337,42,26,131,77,3,127,37,258,125,348,120,237,164,243,160,286,382,55,124,256,14,27,127,121,241,58,354,261,122,350,179,350,343,130,300,349,181,114,377,220,70,325,164,69,84,258,349,110,14,240,357,62,316,299,299,36,216,329,17,330,94,164,240,378,196,164,382,393,320,249,276,301,35,231,134,186,330,337,350,34,282,137,345,313,353,54,100,107,353,54,124,324,353,262,334,332,167,84,75,196,326,129,201,198,140,157,166,284,328,316,332,123,353,350,350,0,45,183,183,47,323,131,62,250,68,125,388,97,156,175,134,325,137,258,154,110,240,386,90,104,84,178,32,39,295,44,369,187,23,6,164,316,20,107,10,246,135,330,246,62,276,240,58,130,371,375,94,149,97,171,81,246,345,324,13,377,345,389,125,170,304,286,310,59},
	{116,241,110,52,306,45,14,32,119,84,157,241,188,237,325,57,276,119,345,348,311,241,323,27,200,373,363,133,312,179,14,348,188,0,228,66,350,350,350,334,268,249,143,333,323,354,354,84,166,341,341,201,27,328,45,334,354,233,198,3,75,179,350,155,155,126,190,393,393,389,10,262,330,347,345,250,125,84,404,125,230,83,114,114,115,345,316,378,386,333,282,91,242,247,189,120,282,240,87,68,377,243,325,20,325,224,92,116,361,124,71,220,301,48,251,325,373,153,313,343,330,284,241,158,387,220,355,186,357,286,62,381,100,254,342,31,139,153,0,126,174,325,225,353,296,349,284,45,284,357,373,159,263,188,164,252,298,355,164,134,330,9,40,340,316,172,328,63,243,389,238,54,355,40,354,150,226,240,240,199,293,330,82,357,374,125,92,267,25,76,189,109,300,373,194,296,340,172,330,97,159,261,327,91,54,284,305,179,263,301,341,11,385,102,14,387,103,393,311,27,229,158,0,92,164,282,159,354,171,350,196,311,339,184,314,378,231,3,166,387,330,237,340,130,317,129,325,318,26,354,348,386,168,14,175,340},
	{21,370,162,244,182,345,171,330,234,103,107,62,297,175,281,279,62,192,343,182,20,62,367,372,282,341,325,116,5,189,404,50,376,23,238,126,189,48,211,121,137,349,278,209,286,349,104,35,116,276,147,243,180,361,363,244,69,166,170,147,2,14,164,325,92,343,283,79,188,223,31,63,343,128,265,265,162,354,127,378,149,125,181,357,10,353,250,175,220,121,75,309,81,136,391,81,263,82,153,292,265,344,340,84,136,305,329,68,294,334,330,268,357,280,241,125,357,300,171,354,331,327,92,114,294,216,162,341,357,354,334,109,10,109,2,325,121,121,92,386,333,323,192,348,163,126,24,282,273,166,143,355,55,375,305,342,14,369,300,345,79,66,335,97,335,378,125,142,114,268,336,343,220,7,296,286,343,72,236,355,214,377,328,263,234,303,241,362,35,373,77,208,350,90,48,334,241,78,125,354,153,92,15,385,189,158,130,25,191,248,245,332,0,223,332,297,404,348,340,335,164,348,156,162,128,62,375,11,308,220,196,119,228,79,296,304,318,248,127,325,172,121,223,142,357,10,164,378,378,2,170,362,341,246,157,123},
	{363,329,265,265,246,113,175,297,318,183,357,237,354,343,92,132,341,196,249,297,132,83,212,20,333,348,332,354,134,332,332,349,244,350,173,315,117,356,171,250,220,79,186,158,153,158,92,305,182,162,162,121,295,375,325,153,369,118,164,92,189,162,118,179,92,153,175,125,0,308,162,251,334,348,176,187,17,116,116,175,219,404,375,334,243,134,116,340,54,84,340,340,175,116,354,109,128,134,104,10,345,369,369,153,18,330,286,38,249,64,92,249,66,284,0,136,372,347,354,107,386,114,121,188,91,299,331,30,284,348,180,333,80,75,6,37,243,326,326,265,9,232,356,356,137,241,314,349,375,24,355,252,353,246,241,376,344,109,198,324,82,82,108,95,362,84,254,129,84,37,69,228,332,208,307,249,353,367,237,62,353,143,107,134,164,84,254,367,340,232,232,332,378,64,17,19,97,369,250,281,312,171,97,57,97,350,164,36,250,197,179,47,121,121,183,84,346,321,169,378,348,332,155,128,164,348,237,245,105,281,348,324,196,248,245,102,248,375,182,160,372,124,203,294,241,337,129,249,280,352,124,356,34,11,75,107},
	{286,341,83,282,373,240,332,372,329,84,164,167,14,40,355,353,129,57,345,313,63,318,121,328,375,295,81,134,189,241,241,354,137,156,188,244,330,330,178,164,65,311,306,154,107,107,354,9,81,232,325,319,348,357,301,251,243,325,208,247,325,167,104,323,68,75,8,385,324,24,189,350,104,31,0,156,143,129,335,313,184,340,190,354,129,284,341,120,345,15,262,325,84,355,186,325,84,264,335,353,249,197,331,350,284,376,305,378,387,309,84,355,153,188,156,70,116,249,65,330,328,357,354,201,174,45,261,350,126,8,159,227,294,330,47,330,355,327,166,296,226,261,261,92,329,339,107,246,348,232,117,305,348,70,207,331,116,121,180,194,348,326,350,308,376,25,0,241,182,311,279,284,26,37,62,5,175,325,375,305,35,234,250,232,354,125,179,174,246,376,349,126,288,326,334,182,372,372,180,180,354,172,184,330,48,164,182,334,32,370,183,333,196,391,294,249,307,375,231,231,127,250,17,168,226,102,330,241,381,120,81,168,136,136,121,349,309,128,278,256,334,329,376,343,294,40,36,58,164,335,320,348,131,55,31,241},
	{92,333,281,179,246,350,30,164,364,341,166,378,363,335,183,335,241,261,125,188,109,263,123,385,129,18,110,192,79,162,129,156,193,164,45,164,249,212,175,70,334,378,173,164,173,227,347,232,279,347,135,350,286,330,24,250,251,70,24,182,250,129,378,385,342,120,405,229,405,336,376,181,77,143,192,330,108,345,140,355,250,171,341,286,332,314,333,129,354,344,116,325,59,38,325,59,384,113,250,348,348,21,88,354,16,29,348,278,35,84,103,230,288,129,199,376,57,348,376,376,129,375,335,254,375,258,246,130,137,355,186,30,5,211,348,254,124,320,171,56,228,228,220,393,14,280,304,134,149,342,339,373,348,224,84,62,321,84,103,375,375,254,226,348,184,320,199,96,341,372,250,11,354,330,208,20,0,84,221,241,148,258,126,242,392,196,129,77,91,263,378,102,349,23,169,138,337,382,58,0,154,144,211,286,335,154,36,164,135,282,239,129,348,354,373,172,249,253,92,348,21,382,291,276,253,164,166,166,148,125,339,304,14,154,306,355,171,37,32,59,74,16,167,279,229,229,81,355,179,104,345,70,309,375,134,348},
	{241,104,98,144,241,309,309,84,376,335,15,65,154,317,353,353,110,355,10,10,84,354,317,345,348,11,40,404,228,57,357,302,96,55,118,261,355,263,200,132,301,226,318,37,271,211,350,129,243,118,148,166,158,164,372,284,404,348,65,335,332,325,16,26,92,244,278,239,333,14,240,125,381,125,54,92,57,358,79,81,333,343,17,256,182,158,5,363,121,26,299,216,57,166,14,130,58,286,369,14,158,240,263,375,0,286,321,284,11,335,20,35,157,173,330,332,158,372,56,134,360,284,125,226,348,158,344,330,330,220,83,304,84,0,84,6,110,92,92,332,100,15,345,340,136,233,184,189,189,235,284,294,92,373,136,189,311,166,220,375,137,330,278,325,330,310,354,158,75,70,246,227,92,194,350,96,250,369,130,100,61,125,179,250,125,325,136,250,179,158,282,92,100,125,100,345,102,189,284,31,158,128,92,330,62,310,354,96,130,250,128,249,130,50,136,375,33,92,97,57,391,375,279,335,251,91,284,129,102,95,40,335,122,249,337,297,208,241,175,375,367,14,337,116,279,95,375,342,40,330,348,175,136,330,345,330},
	{345,345,66,84,249,249,128,114,92,79,343,64,114,30,306,340,129,348,258,343,349,278,241,320,92,343,349,75,82,344,220,295,282,349,349,136,334,204,35,353,375,338,80,336,191,281,345,268,384,340,348,348,297,37,110,282,110,340,373,378,374,96,386,386,369,97,84,125,65,171,309,346,164,217,226,377,88,348,134,220,367,348,348,250,371,237,14,338,250,20,55,389,306,378,47,372,352,340,343,348,120,110,284,245,334,284,112,70,115,102,251,121,129,117,87,346,325,282,377,314,189,369,194,179,121,345,338,98,77,19,311,348,162,378,152,250,329,354,308,92,375,258,50,159,75,152,348,284,313,57,11,31,353,145,127,246,287,3,354,334,36,129,332,329,329,90,295,21,121,131,356,373,356,70,117,32,291,129,143,250,48,334,299,324,332,81,157,302,348,208,349,377,232,385,31,35,384,92,241,304,383,325,134,247,68,374,393,388,243,385,167,125,92,331,178,282,16,117,233,354,335,340,233,284,341,284,122,117,75,376,309,335,84,240,313,158,241,354,386,381,330,121,349,315,332,201,35,83,378,346,345,120,341,91,221,340},
	{197,347,325,337,308,377,278,125,238,318,120,123,91,350,189,334,189,331,244,373,342,309,297,9,37,369,348,126,355,335,334,306,220,220,375,354,234,48,247,164,196,196,279,372,195,125,363,389,166,404,362,340,103,330,385,5,5,130,372,348,334,126,182,371,332,321,57,340,366,273,330,367,72,374,334,158,75,350,136,92,392,127,20,121,381,329,365,367,375,127,304,365,240,283,341,362,304,58,299,332,92,128,131,369,400,348,2,369,232,121,335,348,348,278,255,400,243,72,302,116,377,109,348,350,140,354,125,121,70,372,341,360,162,282,325,31,164,348,15,372,345,75,39,325,39,220,31,255,349,158,35,335,212,119,360,348,58,369,345,70,345,92,66,84,258,92,129,114,306,255,278,241,320,343,348,343,92,258,126,121,223,134,344,204,340,75,178,338,295,83,281,80,136,374,97,110,237,389,284,338,367,297,373,62,377,47,250,371,14,348,348,152,162,284,98,284,129,121,36,378,282,117,57,96,251,102,343,348,374,87,333,29,122,340,377,129,329,354,127,329,90,353,121,152,293,295,395,247,378,388,221,70,385,81,143,325},
	{354,291,282,311,31,167,384,299,304,282,348,197,35,65,120,125,335,342,347,325,75,354,341,31,386,3,345,62,189,233,340,196,58,297,335,220,9,284,243,189,130,182,372,125,195,304,365,127,158,240,136,345,243,369,35,97,243,114,331,92,114,107,173,330,330,123,168,107,70,173,69,126,241,37,164,61,323,15,286,332,83,375,375,345,345,284,40,121,319,348,319,348,345,6,115,75,40,333,119,345,154,87,134,240,330,119,109,354,378,124,82,330,123,326,119,18,62,387,82,348,375,10,30,3,232,199,232,96,199,353,64,196,294,339,119,184,196,196,196,3,184,354,208,14,354,124,317,184,232,330,348,354,196,40,304,119,136,11,373,357,84,23,95,307,348,108,323,236,123,79,304,323,368,375,77,378,284,14,386,77,102,233,78,181,307,283,152,84,312,348,37,184,110,82,175,170,121,87,233,386,124,340,364,128,87,361,125,350,343,373,281,18,18,249,281,42,361,377,157,360,47,35,279,310,229,94,332,181,125,299,84,304,48,48,375,92,370,70,130,338,45,357,10,359,157,83,25,92,283,348,390,84,96,269,363,168},
	{348,7,35,323,375,383,16,357,366,57,360,345,240,278,323,350,130,382,332,361,14,70,286,345,0,341,173,382,361,11,373,84,357,95,23,363,332,7,370,123,375,79,304,236,15,96,378,100,77,125,12,284,312,102,152,56,184,81,110,348,364,375,124,121,386,170,175,361,386,87,130,249,373,157,281,84,70,92,286,279,47,14,377,94,229,57,157,83,383,84,390,269,363,345,360,357,366,278,350,88,37,330,281,201,338,330,36,110,36,372,331,305,388,388,164,133,84,371,88,241,278,248,349,332,386,136,246,62,47,35,373,316,245,33,62,330,369,136,356,250,129,250,40,123,342,386,311,74,169,88,301,50,330,371,297,349,250,125,252,305,385,325,175,250,58,249,386,309,250,37,120,127,127,128,362,356,77,360,389,389,224,10,329,143,73,136,84,35,125,227,375,302,356,224,241,356,244,320,303,348,209,171,186,6,65,148,320,124,386,228,242,378,250,369,375,84,226,378,278,20,208,134,164,93,348,92,74,332,128,74,378,392,149,380,102,248,153,333,65,175,233,375,129,311,23,125,55,127,14,332,74,92,250,92,286,316},
	{50,145,212,334,21,342,392,198,286,167,352,128,39,127,0,302,125,241,328,325,46,129,252,212,134,212,178,175,163,118,134,37,328,251,309,20,389,245,348,62,387,23,387,231,375,374,63,375,354,74,73,45,352,376,375,367,35,41,125,320,305,134,84,389,65,233,262,257,309,367,318,125,59,54,241,302,244,369,63,309,92,212,226,172,360,14,38,175,168,50,305,375,297,330,153,92,385,244,375,226,387,166,13,362,254,17,318,134,61,28,332,79,40,376,73,20,50,50,136,136,170,302,127,127,240,168,73,51,100,362,55,14,14,378,134,40,127,73,39,92,329,356,209,170,169,375,356,375,31,40,71,325,173,170,332,325,390,158,335,255,335,212,302,250,252,51,390,330,153,241,170,282,95,57,82,250,309,74,74,95,159,258,179,2,92,134,305,146,0,345,186,141,250,404,160,320,375,345,309,59,350,354,34,367,102,137,325,356,336,56,341,79,258,278,152,286,319,241,303,75,199,241,184,264,152,243,381,114,116,250,152,62,171,56,5,373,79,152,346,231,11,97,97,228,378,261,75,6,377,375,220,143,372,375,284,237},
	{77,95,134,334,101,344,139,251,377,386,375,281,167,354,280,353,355,349,372,323,84,247,377,348,171,372,369,167,386,121,324,46,121,140,348,231,243,103,209,237,100,11,178,225,167,264,262,92,346,332,42,49,292,344,353,114,286,84,386,84,357,12,369,354,357,306,97,373,331,355,175,334,33,381,325,341,342,372,128,369,21,168,82,79,170,91,273,140,119,348,92,383,77,354,125,114,162,229,164,164,175,170,34,367,102,341,56,258,381,75,178,264,114,97,143,175,377,375,348,116,373,164,220,247,284,359,375,128,377,251,175,128,372,84,167,209,11,121,103,324,167,46,386,49,84,92,357,286,229,355,331,369,175,372,170,336,97,47,47,232,391,15,156,156,47,348,15,15,15,15,0,15,8,47,15,233,35,263,216,216,373,46,388,348,259,15,79,284,263,168,55,31,88,243,354,354,241,343,348,104,181,241,367,324,316,384,350,309,357,130,333,344,79,329,309,75,119,372,376,130,355,325,166,37,34,208,311,375,348,132,124,373,56,77,62,238,378,65,363,306,286,348,250,131,121,68,353,189,13,92,200,348,129,383,169,343},
	{318,295,284,306,227,115,208,73,132,341,343,21,353,334,249,315,378,249,62,62,316,131,309,69,348,0,314,101,329,284,36,297,362,253,83,166,301,121,164,97,157,12,54,378,231,119,56,175,353,377,130,354,46,153,325,309,348,302,355,179,14,221,354,305,299,73,299,345,42,37,309,354,284,373,353,357,75,15,123,75,331,120,249,59,302,325,201,348,96,220,39,172,343,302,284,375,355,297,302,243,180,220,100,370,5,372,22,37,297,362,372,73,284,174,375,54,170,392,256,243,341,354,348,75,168,134,284,14,220,181,335,299,341,369,308,77,191,15,15,156,164,355,353,179,164,348,313,61,241,352,278,107,354,183,263,248,323,152,84,141,18,80,337,199,336,282,9,355,53,123,335,9,329,134,353,107,303,249,15,232,19,280,11,321,62,388,347,170,152,102,378,284,148,354,106,331,245,375,92,343,115,337,128,330,102,221,159,124,150,374,159,357,345,36,69,330,404,84,354,84,90,109,159,124,94,137,350,20,330,250,164,357,21,334,241,232,247,104,377,304,388,237,162,208,35,353,239,333,57,134,352,127,348,69,345,186},
	{267,11,75,286,135,354,357,115,153,333,333,296,305,194,330,263,40,386,388,347,329,333,357,127,352,14,184,33,175,168,349,381,116,127,345,370,323,127,340,61,14,343,14,366,325,374,184,278,170,238,74,188,347,272,150,83,188,388,155,166,360,31,353,241,345,31,360,171,251,330,83,360,375,353,66,249,385,229,377,348,88,354,133,349,391,184,373,340,69,373,82,355,84,357,303,310,242,320,393,107,97,297,238,39,391,194,160,46,39,353,314,375,332,126,36,349,316,128,186,148,298,162,240,391,106,345,277,210,383,175,158,345,306,229,369,45,304,391,383,50,154,309,332,70,116,340,337,304,249,45,357,78,143,296,189,251,39,54,357,352,4,367,106,305,126,234,35,354,164,362,160,348,126,21,128,330,304,238,216,348,164,134,345,348,210,263,343,285,345,171,189,189,210,336,128,284,189,345,15,23,284,353,284,348,164,376,347,167,330,130,130,249,348,168,59,371,171,238,249,6,84,373,375,6,176,84,200,64,332,127,147,42,386,79,354,329,107,89,241,183,260,62,294,330,348,30,348,316,330,405,243,249,125,371,347,349},
	{224,80,373,337,69,356,376,84,232,265,336,75,136,73,96,349,243,8,330,258,33,215,82,357,348,246,232,104,114,349,137,64,348,376,330,87,260,123,303,141,355,175,0,326,74,386,208,316,284,193,232,143,171,19,303,116,20,232,354,294,393,21,377,310,124,373,284,389,375,134,312,348,348,341,371,228,110,273,283,389,389,20,378,37,358,238,314,243,84,368,184,345,84,164,356,232,346,8,20,129,250,340,374,198,330,330,62,124,198,304,282,348,294,152,138,11,125,385,337,114,128,37,145,179,237,284,197,143,349,137,377,38,333,314,196,162,92,354,340,258,392,375,248,293,164,332,337,251,232,348,378,333,194,149,220,332,332,339,137,29,160,92,232,263,189,348,349,101,3,67,353,273,142,243,176,294,0,64,107,356,375,145,249,334,372,353,361,309,54,98,114,376,316,404,188,159,323,386,357,11,329,297,354,31,313,20,107,124,114,135,83,31,323,375,320,341,329,354,311,152,385,177,337,246,282,107,177,347,134,366,134,332,312,183,240,164,226,356,36,90,164,307,19,378,373,316,172,391,134,32,355,125,89,64,306,32},
	{178,149,171,232,175,164,244,239,135,193,391,231,3,232,332,344,383,164,143,146,302,154,70,383,44,386,374,12,212,387,74,345,66,348,243,383,92,354,130,100,184,32,319,330,166,306,97,330,286,373,404,188,175,117,16,86,157,144,80,329,200,323,360,116,60,332,0,123,167,78,187,139,346,284,166,104,332,70,316,325,323,84,262,92,75,137,373,309,367,116,346,71,331,354,145,283,120,325,84,371,29,245,284,114,153,310,197,127,127,115,315,387,119,347,193,125,71,125,295,153,116,341,372,129,373,15,376,386,339,347,186,225,2,87,243,186,301,302,227,331,166,301,139,172,389,347,400,327,261,305,301,244,164,293,383,20,226,268,232,271,89,386,329,350,120,311,172,139,300,284,296,323,109,373,373,179,348,355,305,212,330,124,91,180,135,295,389,301,0,83,326,199,175,301,223,389,317,339,100,341,166,296,5,182,196,179,14,325,172,62,270,387,348,175,5,145,244,52,241,32,305,182,352,31,83,131,16,286,404,339,48,173,360,360,26,164,331,330,141,290,13,370,243,36,175,117,92,240,299,244,238,170,273,339,332,36},
	{153,294,172,203,120,235,299,79,127,251,346,305,333,354,128,392,168,245,160,73,336,360,241,125,376,61,344,350,73,136,400,360,240,312,0,370,66,278,139,125,81,299,175,135,121,354,166,385,272,243,385,162,14,312,341,347,74,104,305,250,82,55,11,348,2,387,343,64,378,113,383,92,212,110,123,247,18,350,153,214,340,125,125,243,29,375,192,164,162,92,390,152,279,231,156,70,356,46,404,16,10,175,332,151,173,75,175,336,125,158,20,243,220,31,333,125,330,100,25,212,162,51,250,226,179,390,176,393,348,136,305,378,158,130,86,348,373,66,371,238,168,316,243,42,278,330,79,64,187,405,346,30,337,87,21,303,134,73,33,376,199,11,89,8,243,220,246,137,329,96,141,80,123,315,215,224,354,243,374,243,97,20,143,238,21,20,356,390,198,304,124,63,353,312,20,171,293,243,184,228,284,341,302,14,208,232,74,337,142,160,77,183,344,353,36,124,347,203,375,36,314,404,64,349,139,367,378,332,66,67,332,117,251,276,105,64,91,194,374,273,128,348,31,38,305,3,349,263,378,160,240,354,157,307,166,145},
	{334,301,164,366,40,104,90,75,339,54,177,83,336,172,139,125,265,309,159,246,134,1,244,372,221,54,184,12,348,60,143,154,32,330,97,179,44,383,130,375,332,135,123,229,304,66,125,134,188,386,245,350,139,244,294,75,29,127,376,71,296,120,119,2,70,186,174,386,81,186,196,373,20,91,212,305,135,212,199,172,90,9,348,124,18,261,16,305,182,179,13,352,131,62,389,341,172,31,136,168,240,175,73,158,240,51,244,61,123,162,341,385,166,348,29,16,156,31,333,370,370,133,5,65,136,168,208,370,187,180,289,278,278,187,345,14,107,14,278,243,141,13,114,266,270,332,332,125,193,331,291,69,367,203,369,231,331,171,100,14,266,110,323,91,91,78,40,333,102,193,0,154,167,404,313,276,134,356,356,31,250,170,305,277,154,345,326,345,354,122,354,326,333,10,333,250,220,326,226,349,325,349,155,252,158,281,251,0,310,212,302,139,110,252,43,323,69,241,153,305,323,234,332,330,121,31,232,305,119,302,326,0,187,289,278,345,107,14,326,43,266,325,332,114,125,193,141,187,367,203,102,326,302,193,404,139},
	{78,91,110,154,133,356,159,281,354,345,32,330,326,122,345,75,31,158,250,121,155,252,110,310,302,252,140,119,84,393,161,72,336,243,329,348,375,349,346,69,75,283,8,229,145,357,264,375,232,131,80,346,349,373,129,36,75,250,62,389,393,63,171,1,320,375,11,19,84,92,175,173,35,337,74,174,196,126,286,299,332,77,102,354,87,278,137,127,337,45,329,14,331,278,283,375,240,69,355,373,40,332,59,212,357,332,229,229,388,348,72,178,349,134,44,373,232,171,306,332,175,283,332,349,378,346,259,331,38,345,349,354,62,354,173,325,325,212,383,299,3,120,129,299,349,241,345,121,91,357,329,325,2,330,305,92,370,59,5,330,349,268,256,170,318,61,232,299,299,354,345,82,208,77,92,59,330,349,375,121,173,330,164,164,164,383,252,375,300,137,201,348,252,345,246,243,338,344,92,97,119,375,96,391,47,352,134,40,116,358,179,354,39,64,299,107,328,290,119,134,358,352,92,330,39,172,164,221,342,358,92,92,354,354,342,199,85,330,198,326,82,227,357,164,37,346,171,162,3,10,329,63,58,116,329,64},
	{340,92,198,35,334,367,313,373,229,186,171,241,377,123,276,81,114,369,349,208,378,319,170,171,68,350,329,171,290,171,331,114,349,181,181,357,172,188,18,329,325,155,349,330,348,2,57,308,332,354,175,173,56,92,227,346,6,232,325,0,330,92,181,329,188,162,164,301,2,81,56,173,171,348,83,164,10,110,110,110,19,247,247,167,310,373,131,36,247,131,167,63,131,310,81,81,142,189,190,190,10,347,310,121,347,91,66,29,243,258,62,70,329,258,246,130,342,215,6,349,268,199,321,389,55,8,348,220,306,14,129,114,228,346,19,349,302,306,129,335,3,3,112,95,242,55,127,313,182,350,299,311,127,341,146,13,302,370,232,155,134,156,367,262,9,0,249,249,281,280,198,134,125,15,62,125,0,306,96,302,11,335,226,91,19,155,305,174,121,127,342,92,125,126,31,302,116,332,243,70,321,125,158,325,258,84,321,251,91,325,280,107,32,155,262,357,281,325,91,84,306,96,357,90,14,342,299,70,321,70,325,258,84,107,325,357,306,133,133,332,335,332,92,349,358,357,280,161,231,350,350,357,231,3,349,333},
	{116,347,66,247,153,333,292,107,340,348,340,97,295,153,241,108,354,323,82,73,62,63,226,238,171,34,131,162,246,127,75,75,325,335,155,282,348,348,143,72,354,237,162,311,124,315,121,153,124,179,313,36,350,357,116,107,131,318,318,236,157,318,386,386,44,66,157,304,107,243,151,389,332,246,348,269,309,75,75,345,326,345,354,381,345,332,336,348,355,271,310,310,126,153,162,160,234,380,182,50,220,109,127,97,343,345,121,278,263,188,18,332,236,175,170,212,251,347,66,247,107,333,292,340,340,323,97,73,241,8,295,108,354,175,171,238,131,129,124,313,110,350,132,143,348,236,239,318,107,350,350,143,309,354,75,381,345,75,212,182,63,271,109,162,31,263,236,251,83,67,98,84,331,369,228,268,84,303,169,92,341,334,134,16,294,325,346,220,296,139,296,79,172,330,172,234,234,172,16,16,16,168,16,273,83,339,83,346,369,16,268,134,294,296,220,172,234,16,16,81,79,81,81,284,284,24,92,66,294,320,369,300,333,384,258,354,346,284,349,79,79,300,349,378,348,393,14,129,306,10,47,312,294,10,284,74},
	{106,258,310,128,124,19,220,314,47,333,346,135,77,345,161,330,24,20,205,75,21,137,69,297,354,330,220,154,104,284,125,383,19,332,21,347,304,81,370,325,100,75,218,357,116,120,312,121,369,115,110,337,82,325,97,29,295,305,20,90,330,153,172,296,332,347,326,196,305,182,14,354,339,130,270,318,381,278,37,57,348,241,256,36,352,306,325,333,369,82,106,188,345,196,31,333,179,360,202,284,66,92,320,305,319,330,258,354,37,79,349,125,284,10,294,74,348,77,256,333,124,161,128,330,19,20,69,75,354,205,137,104,122,332,100,29,153,97,296,31,347,196,20,172,339,130,182,270,381,202,285,153,104,333,82,20,208,14,238,316,107,81,125,3,2,84,332,357,336,82,236,336,180,354,237,243,62,320,372,37,343,378,375,229,336,260,268,357,326,375,57,404,353,20,10,150,320,348,250,240,250,132,238,371,355,231,377,134,378,217,134,232,389,124,171,373,368,84,346,284,14,320,320,294,172,180,233,306,375,261,308,68,343,251,282,132,77,106,20,378,349,179,377,57,106,172,134,295,246,183,167,107,316,341,318,137},
	{75,36,337,294,175,383,377,281,233,154,306,157,387,143,241,241,345,81,272,345,91,220,329,233,48,233,243,81,120,243,123,354,309,251,331,387,153,262,294,98,320,318,296,243,36,375,172,231,308,330,26,70,345,355,388,334,278,241,375,290,175,330,179,370,196,220,24,234,48,250,14,375,354,340,117,20,297,334,170,369,73,172,320,28,63,334,312,345,179,369,131,348,347,372,236,377,345,361,404,308,333,92,290,134,330,119,164,234,180,354,320,343,37,250,260,20,404,361,284,294,84,134,388,378,320,217,124,348,303,334,180,349,128,117,179,106,233,234,164,36,345,337,246,137,241,241,143,383,387,297,24,233,375,153,272,329,5,172,243,278,16,179,48,31,377,92,290,333,97,325,325,325,354,88,348,141,315,129,10,11,368,309,62,148,106,334,115,149,91,318,94,233,14,143,242,354,299,174,238,334,227,136,54,151,18,196,168,174,334,70,361,299,309,18,151,175,90,90,127,142,127,160,272,0,154,154,309,80,339,254,184,57,154,18,78,311,232,386,78,254,309,10,14,262,84,77,261,250,95,339,356,92,231,379,280,301},
	{309,164,18,387,309,231,295,374,251,387,292,125,74,116,156,133,241,166,373,18,231,180,270,182,182,275,340,169,243,243,202,119,155,214,18,169,255,69,69,203,333,330,69,107,69,69,133,32,354,354,91,345,164,336,102,387,172,335,279,354,102,186,241,241,86,153,122,6,238,186,340,345,334,167,354,318,241,324,167,325,88,37,234,14,196,241,340,39,345,369,354,59,258,129,6,114,320,64,92,354,117,245,301,108,319,196,129,282,8,355,232,404,326,116,175,358,80,82,199,353,233,196,110,331,335,107,232,171,320,20,249,237,84,14,92,325,250,64,20,353,103,232,209,374,303,228,84,367,134,97,284,68,56,302,242,286,115,373,77,3,325,371,378,349,169,179,314,348,348,19,325,128,148,335,332,91,121,160,84,142,339,74,137,309,190,280,367,301,246,354,205,372,103,94,297,329,249,282,240,119,311,164,276,276,142,188,36,164,388,330,352,282,386,241,374,333,205,45,92,64,245,97,377,68,157,81,208,348,154,175,133,32,131,178,171,388,164,188,387,375,209,116,354,62,284,282,119,309,115,374,378,156,387,364,15,15},
	{119,251,364,325,325,354,45,262,367,120,166,345,249,249,125,14,75,346,84,330,332,331,325,116,284,267,341,326,243,109,329,227,272,172,180,284,284,154,386,308,302,220,91,352,243,241,326,267,282,166,5,161,121,193,92,311,250,125,282,182,330,249,16,92,92,378,126,339,381,352,370,141,342,17,354,250,333,20,128,343,297,120,392,320,278,79,136,170,343,191,330,366,333,82,100,115,150,364,272,369,88,102,350,164,32,162,286,2,263,92,354,116,286,164,169,179,192,373,333,75,175,100,164,332,354,59,92,353,319,175,80,6,110,6,237,209,175,353,367,84,20,10,115,232,303,102,129,142,325,77,314,364,115,150,92,128,332,367,333,343,94,164,166,125,164,284,311,103,276,119,137,92,352,247,171,241,388,81,154,32,97,208,209,64,131,282,284,386,82,65,14,32,309,326,325,269,75,249,84,120,251,126,15,272,5,241,302,100,220,227,243,161,16,342,17,182,193,352,325,330,102,278,170,392,116,88,164,369,100,252,348,84,164,375,21,345,84,371,92,83,263,345,284,83,194,10,355,375,116,246,102,82,326,369,284,354},
	{85,220,136,136,232,119,373,10,345,344,374,80,83,326,223,56,91,263,171,192,84,320,326,164,15,375,91,355,47,250,334,37,57,134,220,97,376,354,346,354,344,312,354,310,350,72,329,77,98,2,375,345,113,334,124,169,378,346,348,114,175,263,197,91,258,334,339,377,37,179,113,209,75,176,124,92,316,135,320,240,329,135,354,20,137,137,14,330,137,134,316,131,309,75,75,152,116,329,282,157,128,226,175,232,286,84,344,385,231,249,243,11,64,175,252,125,134,316,344,355,241,164,347,383,146,74,154,283,241,131,348,348,247,386,157,68,241,317,94,134,250,348,392,92,286,0,37,191,262,344,249,309,116,309,75,129,184,84,45,316,345,110,355,233,154,186,116,350,375,329,134,68,244,80,116,350,355,332,327,284,110,40,305,331,267,172,92,116,243,343,107,47,47,348,220,345,92,164,310,147,309,309,348,316,180,334,90,310,35,92,317,372,5,220,348,223,37,375,172,352,404,14,290,385,354,329,136,349,309,294,128,348,117,14,350,297,120,79,128,168,345,90,133,332,332,316,181,392,354,350,175,317,332,342,348,232},
	{378,179,330,348,92,363,354,369,347,346,232,214,116,189,350,188,62,356,354,162,21,175,110,173,290,356,350,251,250,164,176,211,133,92,355,194,284,223,344,244,10,373,97,68,175,344,334,346,171,37,250,355,342,320,294,375,77,98,339,113,377,91,176,114,329,20,164,135,116,75,354,332,309,329,252,191,3,154,11,231,243,45,94,355,297,116,110,75,97,249,47,186,329,348,220,327,172,92,348,125,110,348,350,372,172,168,128,133,354,175,119,369,350,116,188,100,290,175,130,171,125,332,54,125,125,345,54,175,353,50,92,228,50,228,378,137,378,125,189,189,354,172,35,253,170,208,241,175,133,253,131,294,333,345,124,189,164,281,370,170,131,241,171,345,50,181,181,110,33,84,190,190,84,228,250,250,197,84,345,157,250,190,37,83,84,250,190,180,196,185,121,196,388,0,82,120,120,130,101,310,315,114,117,152,114,286,164,209,37,111,111,348,243,57,330,319,196,196,243,56,40,353,369,348,331,345,250,186,345,247,356,164,305,70,24,345,345,345,373,3,373,384,24,348,186,369,345,70,175,375,82,84,84,193,193,355},
	{50,250,371,321,378,375,188,5,17,320,14,355,371,320,66,189,200,373,386,97,97,68,82,306,355,232,32,90,241,355,305,308,286,286,82,81,326,81,64,320,376,250,283,284,353,284,313,329,330,131,122,330,345,316,294,330,332,345,162,14,220,249,107,329,329,148,335,110,367,339,327,367,216,202,386,368,92,386,92,92,241,92,37,35,35,110,344,349,335,10,363,335,386,37,345,367,311,171,171,40,251,335,349,212,133,220,46,357,354,40,348,208,367,388,250,357,345,354,75,328,348,54,388,63,40,130,344,37,35,110,349,134,171,10,311,386,349,354,46,250,328,183,227,328,227,345,183,173,95,143,55,171,55,173,95,140,249,249,17,102,356,44,110,136,335,356,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};

	  
  const   char   *RomecharIndex[KRomeCodeNum]   =     
  {   
	  "1","2","3","4","5","6","7","8","9","10","","","","","","",   
		  "1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20",   
		  "1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20",   
		  "1","2","3","4","5","6","7","8","9","10","","",   
		  "1","2","3","4","5","6","7","8","9","10","","",   
		  "1","2","3","4","5","6","7","8","9","10","11","12","",""   
  };


int u2slen(const u2char* str) {
	const u2char* ptr = str;
	int len = 0;
	
	while (ptr && *ptr) {
		ptr ++;
		len ++;
	}
	return len;
}

void u2scpy(u2char* des,const u2char* src) {
	const u2char* ptrSrc = src;
	u2char* ptrDes = des;
	while (ptrSrc) {
		*ptrDes = *ptrSrc;
		if (0 == *ptrSrc)
			break;
		
		ptrDes ++;
		ptrSrc ++;
	}
}

int u2scmp(const u2char* str1,const u2char* str2) {
	const u2char* ptr1 = str1;
	const u2char* ptr2 = str2;

	while (ptr1 && ptr2) {
		if (*ptr1 > *ptr2)		
			return 1;
		else if(*ptr1 < *ptr2)
			return -1;
		
		if (!(*ptr1 && *ptr2))
			break;
		
		ptr1 ++;
		ptr2 ++;
	}
	if (ptr1 && *ptr1)// && (!ptr2||!(*ptr2)))
		return 1;
	
	if (ptr2 && *ptr2)
		return -1;
	
	return 0;
}

void getSortString(SearchSort *node)
{
    u2char sortString[256];
	int pos = 0;
	int lenmax = 127;
    int i;
    WordCode code;
    
	// 提取字符码部分组成字符串，用于排序比较
	for ( i = 0; i < node->data->WordCodeNum && i < lenmax; i++ ) {
		Word2Code(node->data->WordCodeArray[i], &code);
		
		if( code.PyCodeNum > 0 ) {
			sortString[pos++] = PinYinCodeIndexSort[code.PyCodeIndex[0]]; // 汉字，添加第一个拼音做为排序key
			sortString[pos++] = code.Word; // 汉字，添加汉字做为排序key1
        } else {
			sortString[pos++] = 0xFFFF;
			sortString[pos++] = code.Word | 0xFF00; // 非汉字
        }
        
    }
	
	if ( pos <= 0 ) {
		//未命名处理
		sortString[pos++] = 0xFFFF;
		sortString[pos++] = 0xFFFF;
    }
    
	node->iSortString = (u2char*)malloc(SIZEOF_U2Char*(pos+1));
	memcpy(node->iSortString,sortString,SIZEOF_U2Char*pos);
	node->iSortString[pos] = '\0';
}

int SearchSortCmp(void const* item1,void const* item2)
{
    SearchSort *node1 = (SearchSort*)item1;
    SearchSort *node2 = (SearchSort*)item2;
    if (node1->matchAllInPy != node2->matchAllInPy)
        return node2->matchAllInPy - node1->matchAllInPy;
    
    if (node1->matchAllInWord != node2->matchAllInWord)
        return node2->matchAllInWord - node1->matchAllInWord;
    
    if (node1->matchStart != node2->matchStart)
        return node1->matchStart - node2->matchStart;
        
    if (node1->matchEnd != node2->matchEnd)
        return node2->matchEnd - node1->matchEnd;
    
    if (!node1->iSortString) {
        getSortString(node1);
    }
    if (!node2->iSortString) {
         getSortString(node2);
    }
    return u2scmp(node1->iSortString,node2->iSortString);
}

//PinYinCode 按拼音排序后存入PinYinCodeIndexSort
void SortPinYinCodeIndex(){
	int low = 0;
	int mid = 0;
	int high = 0;
	int i = 0;
	int j = 0;
	int val = 0;
	BOOL exist = FALSE;
	int midIndex = 0;
	int sort[KPyCodeNum];

	for (i = 0; i < KPyCodeNum ; i ++) {
		low = 0;
		high = i - 1;
		exist = false;
		while (low <= high) {
			mid = (low + high) >> 1;
			midIndex = sort[mid];
			val = strcmp(PinYinCode[midIndex], PinYinCode[i]);
			if (val < 0)
				low = mid + 1;
			else if (val > 0)
				high = mid - 1;
			else {
				exist = TRUE;
				break;
			}
		}
		if (exist) low = mid;
	
		for (j = i; j > low; j --)
			 sort[j] = sort[j-1];
		sort[j] = i;
	}

	for (int i = 0; i < KPyCodeNum; i ++)
		PinYinCodeIndexSort[sort[i]] = i;
}


void SearchTreeInit(SearchTree* tree)
{
	int i = 0;
	ArrayInit(&tree->SearchDataArray);

	for(i = 0;i < KCachedHitNum;i ++)
		ArrayInit(&tree->iCachedHits[i]);

	tree->iMatchFunc = 0;
	tree->iCurSeachData = 0;
	ArrayInit(&tree->iMatchTrace);
	
	//PinYinCode排序
	if (!isPinYinCodeIndexSorted) {
		isPinYinCodeIndexSorted = TRUE;
		SortPinYinCodeIndex();
	}
    
    ArrayInit(&searchPosMallocArray);
    
    for (int i = 0; i < KPyCodeNum; i ++) {
        PinYinNum[i] = i;
    }
}

void Tree_AddData(SearchTree* tree, long aID, const u2char* aText,const u2char* aPhoneNum)
{
	SearchData* data = 0;
	int len = 0;
	int size = 0;
	
	int pos = FindSearchDataInsertIndex(&tree->SearchDataArray,aID);
	if( pos < 0 )  //已存在
		return;

	data = (SearchData*)malloc(SIZEOF_SearchData);
	data->id = aID;
	data->iPhoneNum = NULL;
    data->WordCodeNum = 0;
    data->WordCodeArray = NULL;
	
	Text2SearchData( aText, data );
	tree->SearchDataArray.Insert(&tree->SearchDataArray,(long)data,pos);

	//首字母预处理
	AddToCachedHit(tree,data);
	
	if( aPhoneNum )
	{
		len = u2slen(aPhoneNum);
		if( len > 0 )
		{
			size = SIZEOF_U2Char*(len+1);
			data->iPhoneNum = (u2char*)malloc(size);
			u2scpy(data->iPhoneNum,aPhoneNum);
		}
	}
	return;
}

void Tree_ReplaceData(SearchTree* tree, long aID, const u2char* aText,const u2char* aPhoneNum )
{
	Tree_DeleteData(tree,aID);
	
	Tree_AddData(tree,aID,aText,aPhoneNum);
	
	return;
}

void Tree_DeleteData(SearchTree* tree, long aID )
{
	int i = 0;
	int pos = 0;
	Array* cache = NULL;
	SearchData *data = NULL;
	
	for (i = 0; i < KCachedHitNum; i++) {
        cache = &tree->iCachedHits[i];
        pos = FindSearchDataIndex(cache, aID, NULL);
        if (pos >= 0) {
            //找到首字母缓存记录，删除之
            cache->Remove(cache,pos);
        }
    }
        
	
	// 然后从缓存池中删除记录	
	pos = FindSearchDataIndex(&tree->SearchDataArray,aID,&data);
	if (data) {
		FreeSearchData(data);
    }
	
	if (pos >= 0) {
		tree->SearchDataArray.Remove(&tree->SearchDataArray,pos);
	}
	
	return;
}

void Tree_SetMatchFunction(SearchTree* tree,const u2char* aMatchFunc)
{
	int len = 0;
	int size = 0;
	if (tree->iMatchFunc) {
		free(tree->iMatchFunc);
        tree->iMatchFunc = NULL;
    }

	len = u2slen(aMatchFunc);
    if (len) {
        size = SIZEOF_U2Char*(len+1);
        tree->iMatchFunc = (u2char*)malloc(size);
        
        u2scpy(tree->iMatchFunc,aMatchFunc);
    }

	return;
}

void LoadMultiPYinWords(const char* multiPYinPath)
{
    if (iIsMultiPYinWordsLoaded)
        return;
    iIsMultiPYinWordsLoaded = YES;
    
	FILE* file = NULL;
	FILE* fp = NULL;
	int size = 0;
	int i = 0;
	unsigned digital_10 = 0;
	unsigned digital_16 = 0;
	int index = 0;
	char* buf = NULL;
	unsigned char word = 0;
	unsigned char word1 = 0;
	WordCode* cur = NULL;
	BOOL isFileEnd = FALSE;
	
	ArrayInit(&iMultiPyCodeSorted);
	
	//DP("LoadMultiPYinWords 1")
	if( (file = fopen(multiPYinPath,"rb")) == NULL )
		{
//		CloseSTDLIB();// without this, there will be memory leak 
		return;
		}

	buf = (char*)malloc((1024+1));
	
	fp = file;
	while( !feof(fp) )
	{
	size = (int) fread(buf, sizeof(char), 1024, fp);
	buf[size] = '\0';
	if( size < 1024 )
		isFileEnd = TRUE;

	for(i = 0;i <= size;i ++)
		{
		word = *(buf+i);
		
		if( word >= '0' && word <= '9' )
			{
			digital_10 = digital_10*10 + word - '0';
			digital_16 = digital_16*16 + word - '0';
			}
		else if( word >= 'A' && word <= 'Z' )
			{
			digital_10 = 0;
			digital_16 = digital_16*16 + word - 'A' + 10;
			}
		else if( i < size || isFileEnd )
			{			
			if( digital_16 > 0x1000 )
				{
				//汉字
				word1 = *(buf+i+1);
				cur = (WordCode*)malloc(SIZEOF_WordCode);
				cur->Word = digital_16;
				cur->PyCodeNum = 0;
				cur->PyCodeIndex = (int*)malloc(SIZEOF_INT*KMaxPyCode);
				//DP1("cur->Word %d",cur->Word)
				index = FindIndexInMultiPYin(cur->Word);
				if( index >= 0 )
					{
					FreeWordCode(cur);
					cur = NULL;
					}
				else
					iMultiPyCodeSorted.Insert(&iMultiPyCodeSorted,(long)cur,-index-1);
				}
			else if( digital_10 > 0 && cur )				
				{									
				cur->PyCodeIndex[cur->PyCodeNum++] = digital_10;
				//DP1("digital_10 %d",digital_10)
				}
			
			digital_10 = digital_16 = 0;
			}
		}
	}
	
	fclose(file);
//	CloseSTDLIB();// without this, there will be memory leak 
	
	free(buf);
	
	return;
}

BOOL IsMatchByKmp(const u2char* aText,const u2char* wordInput,Array* iMatchPosInPinYin)
{
	int i,j;
	int len1 = 0;
	int len2 = 0;
	int p1 = 0;
	int p2 = 0;
	int k = 0;
	
	iKmpBuf[0] = 0;
	j = 0;	
	len1 = u2slen(wordInput);
	for(i = 1; i < len1 ;i ++)
		{	
		while( wordInput[j] != wordInput[i] && j > 0)
			j = iKmpBuf[j-1];
		
		if( wordInput[j] == wordInput[i] )
			j ++;
		
		iKmpBuf[i] = j;
		}
		
	j = 0;
	len2 = u2slen(aText);
	for(i = 0;i < len2;i ++ )
		{
		while(wordInput[j] != aText[i] && j > 0)
			j = iKmpBuf[j-1];
		
		if(wordInput[j] == aText[i]) 
			j ++;
		if( j >= len1 )
			{
			if( iMatchPosInPinYin )
				{
				p1 = i - j +1;
				p2 = p1 + j;
				for(k = p1;k < p2;k ++)
					{
					//DP1("k: %d",k)
					iMatchPosInPinYin->Append(iMatchPosInPinYin,k);
					}
				}
			return TRUE;//i - j +1; 匹配定位
			}
		}
	
	return FALSE;
}

int FindSearchDataIndex(Array* ptr,long aID,SearchData** data)
{
   int low = 0;
   int high = (int) ptr->size - 1;
   int mid;
   SearchData* temp;
   
   while (low <= high) {
	   mid = (low + high) >> 1;
	   temp = (SearchData*)(ptr->GetValue(ptr,mid));
	   
	   if (temp->id < aID) {
		   low = mid + 1;
	   } else if(temp->id > aID) {
		   high = mid - 1;
	   } else {
           if (data) {
               *data = temp;
           }
		   return mid;
	   }
   }

   return -(low+1);
}

int FindSearchDataInsertIndex(Array* ptr,long aID)
{
	SearchData* data = 0;
	int pos = FindSearchDataIndex(ptr,aID,&data);
	if( pos < 0 )
		return - pos - 1;
	else
		return -1;
}

void Text2SearchData(const u2char* aText,SearchData *data)
{
	const u2char* ptr = aText;
	u2char character;
	int count = u2slen(aText);

    // 遍历各个字符，转换为WordCode数组后保存
    data->WordCodeArray = NULL;
    data->WordCodeArray = 0;
    if (count > 0) {
        data->WordCodeArray = (u2char*)malloc(count*SIZEOF_U2Char);
        
        while ( ptr && *ptr ) {
            character = *ptr;
            ptr ++;
            
            if ( character != ' ' ){
                data->WordCodeArray[data->WordCodeNum++] = character;
            }
        }
    }
	
	
	return;
}

BOOL Word2Code( u2char aWord, WordCode *code )
{
	 unsigned char t1 = (aWord >> 8) & 0xFF;
	 unsigned char t2 = aWord & 0xFF;
	 int PyIndex;
	 u2char word = 0;
	 int index;

	code->Word = aWord;
	code->PyCodeNum = 0;

    if( word == ' ') {
        return FALSE;
    } else if( t1 == 255 ) {  
		// 全角ASCII
		if(t2 >= 33 && word <= 58) {
			// 大小写转换
			word = t2 - 33 + 'a';
			code->Word = word;
        } else if(t2 >= 65 && word <= 90) {
			word = t2 - 65 + 'a';
			code->Word = word;
        }
    } else if( t1>= 78 && t1 <= 159 ) {
		// 一般汉字处理
		PyIndex =(int) PyCodeIndex[t1-78][t2];
		if( PyIndex > 0 ) {
			// 进行多拼音处理
			index = FindIndexInMultiPYin(aWord);
			if( index >= 0 ) {
				//多音字
				WordCode* cur = (WordCode*)iMultiPyCodeSorted.GetValue(&iMultiPyCodeSorted,index);
				code->PyCodeNum = cur->PyCodeNum;
                code->PyCodeIndex = cur->PyCodeIndex;
				}
			else
				{
				// 添加到WordCode
				code->PyCodeNum = 1;
				index =(int)  PyCodeIndex[t1-78][t2] - 1;
				code->PyCodeIndex = (int*)&PinYinNum[index];
				}
			}
		}


	return TRUE;
}

int FindIndexInMultiPYin(unsigned int key)
{
	// 二分法查找确定	
	int low = 0;
	int high = (int) iMultiPyCodeSorted.size - 1;
	WordCode *midVal;

	while(low <= high)
		{
		int mid = (low + high) >> 1;
		midVal = (WordCode *)iMultiPyCodeSorted.GetValue(&iMultiPyCodeSorted,mid);
		
		if( midVal->Word < key )
			low = mid + 1;
		else if(  midVal->Word > key )
			high = mid - 1;
		else
			{
			return mid; // key found
			}
		}
	return -(low+1);
}

void AddToCachedHit(SearchTree* tree, SearchData *aData)
{
	int i = 0;
	int j = 0;
	int capticalIndex = 0;
	WordCode code;
    u2char word;
    
	// 首先添加到全搜索集中
	AddToCachedHitSingle(tree,aData, &tree->iCachedHits[KCachedHitFull]);
	
	for( i = 0; i < aData->WordCodeNum; i++ )
		{
        Word2Code(aData->WordCodeArray[i], &code);
		
		if ( code.PyCodeNum > 0 ) {
			// 具有拼音码的字符，添加到对应的首字母搜索集中
			for ( j = 0; j < code.PyCodeNum; j++ ) {
                word = PinYinCode[ code.PyCodeIndex[j] ][0];
//                if (word >= 'a' && word <= 'z') {
                    capticalIndex = word - 'a'; // 获取字符拼音码的首字母
                    //DP1("AddToCachedHit capticalIndex %d",capticalIndex)
                    AddToCachedHitSingle(tree,aData, &tree->iCachedHits[capticalIndex] );
//                }
            }
			
        } else {
			// 不具有拼音码的字符
			capticalIndex = 0;
			
			if ( code.Word >= 'a' && code.Word <= 'z' ) {
				// ASCII字符，直接添加到对应的首字母搜索集
				capticalIndex = code.Word - 'a';
            } else if( code.Word >= 'A' && code.Word <= 'Z' ) {
				capticalIndex = code.Word - 'A';
            } else if( code.Word >= '0' && code.Word <= '9' ) {
				capticalIndex = code.Word - '0' + KLetterNum;
            } else {
				//添加到单列搜索集中
				capticalIndex = KCachedHitNonAlpha;
            }
			
			AddToCachedHitSingle(tree,aData, &tree->iCachedHits[capticalIndex] );
        }
    }

	return;
}

void AddToCachedHitSingle(SearchTree* tree,SearchData *aData, Array* aCacheArray)
{
	int pos = FindSearchDataInsertIndex(aCacheArray, aData->id);
	if( pos >= 0 )
		{
		// 不存在
			//NSLog(@"pos %d",pos);
		aCacheArray->Insert(aCacheArray,(long)aData, pos);
		}
	return;
}


void Tree_Search(SearchTree* tree, u2char* aText, Array* aSearchedArray,Array* aNameMatchArray, Array* aPhoneMatchArray)
{

	int i = 0;
	int value = 0;
	int count = 0;
	int len = 0;
	int temp = 0;
	u2char* textPtr = 0;
	u2char* buf = 0;
	u2char* bufPtr = 0;
	int pos = 0;
    int curSearchWordNum = 0;

//    NSLog(@"Tree_Search begin 0");
	SearchData* iCurSeachData = tree->iCurSeachData;
	SearchData *dataToSearch = 0;
	Array* cache = 0;
	SearchSort *searchSortPtr = 0;
    int matchCount = 0;

    Array aNameMatchHits;
    Array aPhoneMatchHits;
    
	ArrayInit(&aNameMatchHits);
    ArrayInit(&aPhoneMatchHits);

	if( iCurSeachData )
		FreeSearchData(iCurSeachData);

	iCurSeachData = (SearchData*)malloc(SIZEOF_SearchData);
	iCurSeachData->iPhoneNum = NULL;
    iCurSeachData->WordCodeNum = 0;
    iCurSeachData->WordCodeArray = NULL;

	tree->iCurSeachData = iCurSeachData;

	if( aText )
		Text2SearchData( aText,iCurSeachData );

//    NSLog(@"Tree_Search begin 1");
	// 初步确定搜索集
    curSearchWordNum = iCurSeachData->WordCodeNum;
	if (curSearchWordNum <= 0) {
		if (aText && u2slen(aText) > 0 )
			return;
			
		// 如果搜索串为空，返回全部搜索集
        cache = aSearchedArray ? aSearchedArray:&tree->iCachedHits[KCachedHitFull];
    }
    else if (aSearchedArray) {
        cache = aSearchedArray;
    } else {
        // 先取缓存搜索集
        SearchCachedHit(tree,iCurSeachData->WordCodeArray[0], &cache );
    }
    
    //开辟排序空间
     searchSortPtr = (SearchSort*)malloc(cache->size*sizeof(SearchSort));
//    NSLog(@"Tree_Search begin 3");
    //依次搜索定位，筛选出符合条件的搜索集
    for( i = 0; i < cache->size; i++ ) {
        dataToSearch = (SearchData*)cache->GetValue(cache,i);
        
        value = curSearchWordNum > 0 ? IsHit(tree, dataToSearch, iCurSeachData,FALSE):0;
        if ( value >= 0 ) {
            // 搜索项匹配
            SearchSort *node = &searchSortPtr[matchCount++];
            node->data = dataToSearch;
            node->matchStart = (value >> 24) & 0xFF;
            node->matchEnd = (value >> 16) & 0xFF;
            node->matchAllInPy = (value >> 8) & 1;
            node->matchAllInWord = value & 1;
            node->iSortString = NULL;

            aNameMatchHits.Append(&aNameMatchHits, (long)dataToSearch);
            //NSLog(@"%d %d %d %d %d %d",aID,node->matchStart,node->matchEnd,node->pos,node->matchAllInPy,node->matchAllInWord);
        }
    }
//    NSLog(@"Tree_Search begin 4");
    
    if ( aPhoneMatchArray ) {
        //搜索号码匹配
        len = u2slen(aText);
        buf = (u2char*)malloc(SIZEOF_U2Char*(len+1));
        textPtr = aText;
        bufPtr = buf;
        for (i = 0;i < len;i ++) {
            temp = ChangeWordToDigit(tree,*textPtr);
            *bufPtr = temp;
            bufPtr ++;
            textPtr ++;
        }
        *bufPtr = '\0';
        
        cache = &tree->iCachedHits[KCachedHitFull];
        count = (int) cache->size;
        for (i = 0; i < count; i++) {				
            dataToSearch = (SearchData*)cache->GetValue(cache,i);
            
            if ( !dataToSearch || !dataToSearch->iPhoneNum || u2slen(dataToSearch->iPhoneNum)<len)
                continue;
            
            pos = FindSearchDataIndex(&aNameMatchHits, dataToSearch->id,NULL);
            if ( pos >= 0 )//名字搜索已存在
                continue;

            //号码匹配
            if( IsMatchByKmp(dataToSearch->iPhoneNum,buf,0) ) {
                aPhoneMatchArray->Append(aPhoneMatchArray,dataToSearch->id);
            }
        }

        free(buf);
    } 

//    NSLog(@"Tree_Search begin 5");
    //aNameMatchHits 根据匹配权重排序，获取排序后的ID
    qsort(searchSortPtr,matchCount,SIZEOF_SearchSort,SearchSortCmp);
    
//    NSLog(@"Tree_Search begin 6");
    for (i = 0; i < matchCount; i ++) {
        SearchSort *node = &searchSortPtr[i];
        aNameMatchArray->Append(aNameMatchArray, node->data->id);
        
        if (node->iSortString) {
            free(node->iSortString);
        }
    }
    free(searchSortPtr);
    
    aNameMatchHits.Reset(&aNameMatchHits);
    aPhoneMatchHits.Reset(&aPhoneMatchHits);
//    NSLog(@"Tree_Search begin 8");
}

BOOL SearchCachedHit(SearchTree* tree, u2char word, Array **aHits)
{
	BOOL isMakeSure = TRUE;
	int capticalIndex;
    WordCode code;

//    NSLog(@"SearchCachedHit 0");
    Word2Code(word, &code);
	if( code.PyCodeNum > 0 )
		{
		// 有拼音码的汉字
        capticalIndex = PinYinCode[ code.PyCodeIndex[0] ][0];
        capticalIndex -= 'a';
        *aHits = &tree->iCachedHits[capticalIndex];
        
        isMakeSure = FALSE;
		}
	else
		{
		// 无拼音码
		capticalIndex = 0;
		
		if( code.Word >= 'a' && code.Word <= 'z' )
			{
			// ASCII字母
			capticalIndex = code.Word - 'a'; // 获取字符拼音码的首字母	
			}
        else if( code.Word >= 'A' && code.Word <= 'Z' )
			{
			// ASCII字母
			capticalIndex = code.Word - 'A'; // 获取字符拼音码的首字母
			}
		else if( code.Word >= '0' && code.Word <= '9' )
			{
			capticalIndex = code.Word - '0' + KLetterNum;
			}
		else
			{
			//非字母、数字
			capticalIndex = KCachedHitNonAlpha; // 获取字符拼音码的首字母
			isMakeSure = FALSE;
			}
		
        
        if ( code.Word >= '0' && code.Word <= '9' && tree->iMatchFunc ) {
            //数字键盘 与字母对应
            *aHits = &tree->iCachedHits[KCachedHitFull];
            isMakeSure = FALSE;
        } else {
            *aHits = &tree->iCachedHits[capticalIndex];
            isMakeSure = TRUE;
        }

#if 0  //此段代码效率太慢
		if( code.Word >= '0' && code.Word <= '9' && tree->iMatchFunc )
			{	
			len = u2slen(tree->iMatchFunc);
			if( len <= 0 )
				return isMakeSure;
				
			for( i = 0; i < len; i ++)
				{
				temp = *(tree->iMatchFunc+i);
				if(temp != code.Word)
					continue;
				
				index = i;
				cache = &tree->iCachedHits[index];
				for( j = 0; j < cache->size; j++ )
					{
					data = (SearchData*)cache->GetValue(cache,j);
					pos = FindSearchDataInsertIndex(aHits, data->id);
					if( pos >= 0 )
						{
						//不存在
						aHits->Insert(aHits,(int)data,pos);
						}
					}
				}
			}
#endif
		}
    

	return isMakeSure;
}

/*
 * 确定某一搜索集是否匹配搜索串  return匹配的权值:初位置8bit+末位置8bit+全拼匹配8bit+全汉字匹配8bit,<0为不匹配
 */
int IsHit(SearchTree* tree,SearchData* aData, SearchData* aSearchWordData,BOOL iIsLogTrace)
{	
	int j = 0;
	int k = 0;
	int count = 0;
	int aSearchCount = aSearchWordData->WordCodeNum;
	int aPYinNum = 0;

	int aPos = 0;
	int nWord = 0;
	int nPyCode = 0;
	int nchar = 0;
	int nextword = 0;
	int value = -1;
	int temp1 = 0;
	int temp2 = 0;
    bool isMatchAllPinYin = true;
    bool isMatchAllWord = true;
	
	WordCode code;
    WordCode codeSearch;
	u2char word = aSearchWordData->WordCodeArray[0];
	SearchPos* matchpos = NULL;
	SearchPos* pos = 0;
	SearchPos* nextPos = 0;

	Array* iMatchTrace = &tree->iMatchTrace;
	
    int searchPosUseCount = 0;
    if (aData->WordCodeNum<<2 > searchPosPtrMallocSize || searchPosPtrMallocSize== 0) {
        if (searchPosPtrArray) {
            free(searchPosPtrArray);
        }
        searchPosPtrArray = (SearchPos**)malloc(SIZEOF_INT*aData->WordCodeNum<<2);
        searchPosPtrMallocSize = aData->WordCodeNum<<2;
    }
    
	
	
	// 用户输入字符
	// 对于第一个输入字符，直接定位首字母位置
	for( j = aData->WordCodeNum-1; j >= 0; j-- )
		{
		Word2Code(aData->WordCodeArray[j], &code);
		aPYinNum = code.PyCodeNum;
		if( aPYinNum <= 0 )
			aPYinNum = 1;
		for( k = 0; k < aPYinNum;k ++ )
			{
			if( IsMatch(tree, &code,k,0, word ) )
				{
				// 添加到搜索位置集
				//DP4("Search: Position round=%d,word=%d,pycode=%d,u2char=%d",i,pos->nWord,pos->nPyCode,pos->nchar);
                pos = GetSearchPos(searchPosUseCount++);
                
				pos->pos = (j<<6)|(k<<3);
				pos->iFather = NULL;
				pos->step = 1;
				searchPosPtrArray[count ++] = pos;
				//printf("pos %d\n",pos->pos);
				
				if( aSearchCount <= 1 )
					{
					matchpos = pos;
					break;
					}
				}
			}
		}
		
	// 对于后续的字符，从当前搜索位置开始继续查找可能的匹配项		
	while( 1 )
		{	
		if( count <= 0 )
			break;
		
		count --;
		
		pos = searchPosPtrArray[count];
		
		if(pos->step == aSearchCount)
			{
			matchpos = pos;
			break;
			}
		
		aPos = pos->pos;
		nWord = aPos >> 6;
		nPyCode = (aPos & 63)>>3;  //63=(1<<6)-1
		nchar = aPos & 7;			//7 = (1<<3)-1
		
        word = aSearchWordData->WordCodeArray[pos->step];
        Word2Code(word,&codeSearch);
		if( codeSearch.PyCodeNum == 0 )
			{			
			// 搜索下一个拼音的字母	
            Word2Code(aData->WordCodeArray[nWord], &code);
			if( IsMatch(tree, &code,nPyCode,nchar+1, word ) )
				{
				//DP4("Search: Position round=%d,word=%d,pycode=%d,u2char=%d",i,pos->nWord,pos->nPyCode,pos->nchar);
                nextPos = GetSearchPos(searchPosUseCount++);
				
				nextPos->pos = (nWord<<6)|(nPyCode<<3)|(nchar+1);
				nextPos->iFather = pos;
				nextPos->step = pos->step + 1;
				searchPosPtrArray[count ++] = nextPos;
				}
			}
            
            // 下一个字
            {
            nextword = nWord+1;
            if( nextword < aData->WordCodeNum )
                {
                Word2Code(aData->WordCodeArray[nextword], &code);
                aPYinNum = code.PyCodeNum;
                if( aPYinNum <= 0 )
                    aPYinNum = 1;
                for( k = 0; k < aPYinNum;k ++ )
                    {
                    if( IsMatch(tree, &code,k,0, word ) )
                        {
                        //DP4("Search: Position round=%d,word=%d,pycode=%d,u2char=%d",i,pos->nWord,pos->nPyCode,pos->nchar);
                        nextPos = GetSearchPos(searchPosUseCount++);
                        
                        nextPos->pos = (nextword<<6)|(k<<3);
                        nextPos->iFather = pos;
                        nextPos->step = pos->step + 1;
                        searchPosPtrArray[count ++] = nextPos;
                        }
                    }
                }
            }
		}
    
    
	
	// 如果matchpos为空，则匹配失败
	value = -1;
	if( matchpos )
		{
		value = 0;
		//保存匹配轨迹
		if( iIsLogTrace )
		{
			for(j = 0;j < iMatchTrace->size;j ++)
			{
				pos = (SearchPos*)iMatchTrace->GetValue(iMatchTrace,j);
				FreeSearchPos(pos);
			}

			iMatchTrace->Reset(iMatchTrace);
		}

		pos = matchpos;
		temp2 = pos->pos >> 6;
		temp1 = temp2;
        nextword = -1;
		while(pos)
			{
			if( iIsLogTrace )
				{
				nextPos = (SearchPos*)malloc(SIZEOF_SearchPos);
				nextPos->pos = pos->pos;

				iMatchTrace->Append(iMatchTrace,(long)nextPos);
				}
			
			temp1 = pos->pos;
			if (isMatchAllPinYin)
                {
                //检查是否为全拼:字的最后一个标红的下一位如果是0，该汉字字一定全拼
                nWord = temp1 >> 6;
                if( nextword != nWord )
                    {
                    nextword = nWord;
                    nPyCode = (temp1 & 63)>>3;  //63=(1<<6)-1
                    nchar = temp1 & 7;
                    
                    Word2Code(aData->WordCodeArray[nWord], &code);
                    if (code.PyCodeNum>0 && PinYinCode[ code.PyCodeIndex[nPyCode] ][nchar+1])
                        {//最后一位不为0 非全拼
                        isMatchAllPinYin = false;
                        }
                    }
                }
            
            pos = pos->iFather;
			}
		
		temp1 = temp1 >> 6;
        isMatchAllWord = (temp1==0 && temp2==aData->WordCodeNum-1);
        isMatchAllPinYin &= isMatchAllWord;//非全汉字匹配的一定非全拼音匹配
        
		if( temp1 > 0xFF )
			temp1 = 0xFF;
		
		if( temp2 > 0xFF )
			temp2 = 0xFF;
		
        value = (temp1 << 24) + (temp2 << 16) + (isMatchAllPinYin << 8) + isMatchAllWord;
		}
	
	return value;
}

/*
 * 确定aWordCode串的aPos位置，是否和aWord相匹配
 */
BOOL IsMatch(SearchTree* tree,WordCode* aWordCode,int nPyCode,int nchar, unsigned int aWord )
{
	WordCode* word = aWordCode;
	const char *pyCode = 0;

//	if( nWord >= aWordCode->size )
//		return FALSE;
	
//	 word = (WordCode*)aWordCode->GetValue(aWordCode,nWord);
	
	// 如果aWord为汉字字符，则直接比对GBK码是否一致
	if( aWord & 0xFF00 )
		{
		return CompareWord(tree,word->Word, aWord );
		}
	
	// 对于j,0,0这种情况，如果word为非拼音字符，直接检查字符是否匹配
	if( nPyCode==0 && nchar==0 && word->PyCodeNum == 0 )
		{	
		return CompareWord(tree,word->Word, aWord );
		}
	
	if( nPyCode >= word->PyCodeNum )
		return FALSE;
	
	 pyCode = PinYinCode[ word->PyCodeIndex[nPyCode] ];
	
	if( !pyCode[nchar] )
		return FALSE;
	
	//DP1("pyCode[aPos->nchar] %d",pyCode[aPos->nchar]);
	
	// 最后检查对应字母是否匹配
	return CompareWord(tree,pyCode[nchar], aWord );
}


unsigned int ChangeWordToDigit(SearchTree* tree,unsigned int Word)
{
	int index = 0;
	;
	if( Word >= 'A' && Word <= 'Z' )
		Word = Word - 'A' + 'a';
	
	if( Word >= 'a' && Word <= 'z' && tree->iMatchFunc )
		{
		index = Word - 'a';
		if( index >= 0 )
			Word = *(tree->iMatchFunc+index);
		}
	
	return Word;
}
BOOL CompareWord(SearchTree* tree,unsigned int Word,unsigned int WordInput)
{
    Word = ChangeWordToDigit(tree,Word);
    WordInput = ChangeWordToDigit(tree,WordInput);
	return Word == WordInput;
}

BOOL Tree_GetPinYin(SearchTree* tree,long aID, u2char* aText, Array* iMatchPosInPinYin)
{
	int i = 0;
	int aPos = 0;
	int nWord = 0;
	int nPyCode = 0;
	int nchar  = 0;
	int aPyCodeNum = 0;
	int index = 0;
	int k = 0;

	int len = 0;
	int temp = 0;
	int iMatchNum = 0;
	int iMatchIndex = 0;
	int count = 0;
	
	WordCode code;
	const char *pyCode = NULL;
	SearchData* data = NULL;
	Array* iMatchTrace = &tree->iMatchTrace;
	SearchPos* pos = NULL;

	iMatchPosInPinYin->Reset(iMatchPosInPinYin);
	
	if( FindSearchDataIndex(&tree->SearchDataArray,aID,&data) < 0 )
		return FALSE;
	
	IsHit(tree,data,tree->iCurSeachData,TRUE);
	

	iMatchNum = (int) tree->iMatchTrace.size;
	iMatchIndex = iMatchNum - 1;
	count = data->WordCodeNum;
	for(i = 0; i < count; i ++)
		{
        Word2Code(data->WordCodeArray[i], &code);
		if( code.PyCodeNum == 0)
			{
			aText[len] = code.Word;
			
			//***************************匹配定位
			if( iMatchIndex >= 0 )
				{
				pos = (SearchPos*)iMatchTrace->GetValue(iMatchTrace,iMatchIndex);
				aPos = pos->pos;
				nWord = aPos >> 6;
				nPyCode = (aPos & 63)>>3;  //63=(1<<6)-1
				nchar = aPos & 7;			//7 = (1<<3)-1
					
				if(nWord == i && nPyCode == 0)
					{
					iMatchPosInPinYin->Append(iMatchPosInPinYin,len);
					iMatchIndex --;
					}
				}
			
			len ++;
			//***********************************
			}
		else
			{
			aPyCodeNum = code.PyCodeNum;
				
			index = 0;
			//************************匹配定位
			for(k = iMatchIndex;k >= 0;k --)
				{
				pos = (SearchPos*)(iMatchTrace->GetValue(iMatchTrace,k));
				aPos = pos->pos;
				nWord = aPos >> 6;
				nPyCode = (aPos & 63)>>3;  //63=(1<<6)-1
				nchar = aPos & 7;			//7 = (1<<3)-1
								
				if(nWord == i && nPyCode < aPyCodeNum)
					{
					iMatchPosInPinYin->Append(iMatchPosInPinYin,len+nchar);
					iMatchIndex --;
					
					index = nPyCode;
					}
				else 
					{
					break;
					}
				}
			pyCode = PinYinCode[code.PyCodeIndex[index]];
			
			//拼音首字母大写
			temp = *pyCode;
			if( temp >= 'a' && temp <= 'z' )
				{
				aText[len++] = temp - 'a' + 'A';
				pyCode ++;
				}
			
			while(*pyCode)
				{
				aText[len++] = *pyCode;
				pyCode ++;
				}
			//********************************************
			}
		}

	aText[len] = '\0';
	
	//DP1("PinYin %S",&aText);
	return TRUE;
}

BOOL Tree_GetPhoneNum(SearchTree* tree,long aID, u2char* aText, Array* iMatchPosInPhoneNum)
{
	int i = 0;
	int len = 0;
	u2char* buf = 0;
	u2char* ptr = 0;
	unsigned int temp = 0;
	SearchData *data = NULL;
	SearchData *iCurSeachData = tree->iCurSeachData;
	u2char word;
	
	iMatchPosInPhoneNum->Reset(iMatchPosInPhoneNum);
	
	if( FindSearchDataIndex(&tree->SearchDataArray,aID,&data) < 0 )
		return FALSE;
	
	u2scpy(aText,data->iPhoneNum);
	
	len = iCurSeachData->WordCodeNum;
	buf = (u2char*)malloc(SIZEOF_U2Char*(len+1));
	ptr = buf;
	for(i = 0;i < len;i ++)
		{
		word = iCurSeachData->WordCodeArray[i];
		temp = ChangeWordToDigit(tree,word);
		*ptr ++ = temp;
		}
	*ptr = 0;

	IsMatchByKmp(data->iPhoneNum,buf,iMatchPosInPhoneNum);
	
	free(buf);
	
	return TRUE;
}

SearchPos* GetSearchPos(int index)
{
    SearchPos *ptr = NULL;
    if (index > searchPosMallocSize || searchPosMallocSize == 0) {
        searchPosMalloc = (SearchPos*)malloc(SIZEOF_SearchPos*KSearchPosMalloc);
        searchPosMallocArray.Append(&searchPosMallocArray,(long)searchPosMalloc);
        searchPosMallocSize += KSearchPosMalloc;       
    }
    
    ptr = (SearchPos*)searchPosMallocArray.GetValue(&searchPosMallocArray,index/KSearchPosMalloc);
    ptr += index % KSearchPosMalloc;
    return ptr;
}
void FreeWordCode(WordCode* word)
{
	if( !word )
		return;

	if( word->PyCodeNum > 0 )
		free(word->PyCodeIndex);

	free(word);

	return;
}

void FreeSearchData(SearchData* data)
{
	if( data->iPhoneNum )
		free(data->iPhoneNum);

	if (data->WordCodeNum) {
        free(data->WordCodeArray);
    }

	free(data);
}

void FreeSearchPos(SearchPos* data)
{
	 free(data);
}

void FreeSearchTree(SearchTree* tree)
{
	int i = 0;
	Array* cache = 0;
	if( tree->iMatchFunc ) {
		free(tree->iMatchFunc);
		tree->iMatchFunc = NULL;
	}
	
	cache = &tree->SearchDataArray;
	for(i = 0;i < cache->size;i ++)
		FreeSearchData((SearchData*)cache->GetValue(cache,i));
	cache->Reset(cache);
	
	for(i = 0;i < KCachedHitNum;i ++)
		{
		cache = &tree->iCachedHits[i];
		cache->Reset(cache);
		}
	
	cache = &tree->iMatchTrace;
	for(i = 0;i < cache->size;i ++)
		FreeSearchPos((SearchPos*)cache->GetValue(cache,i));
	cache->Reset(cache);
	
	if( tree->iCurSeachData ) {
		FreeSearchData(tree->iCurSeachData);
		tree->iCurSeachData = NULL;
	}
    
	cache = &searchPosMallocArray;
	for(i = 0;i < cache->size;i ++)
		FreeSearchPos((SearchPos*)cache->GetValue(cache,i));
	cache->Reset(cache);
    
	searchPosMallocSize=0;
	searchPosPtrMallocSize=0;
    
    if (searchPosPtrArray) {
        free(searchPosPtrArray);
        searchPosPtrArray = NULL;
    }
}

void ReleaseMultiPYinWords()
{
	//释放多音字
	if( iIsMultiPYinWordsLoaded )
		{
		int i = 0;
		for( i = 0;i < iMultiPyCodeSorted.size;i ++)
			FreeWordCode((WordCode*)iMultiPyCodeSorted.GetValue(&iMultiPyCodeSorted,i));
		
		iMultiPyCodeSorted.Reset(&iMultiPyCodeSorted);
		
		iIsMultiPYinWordsLoaded = FALSE;
		}
}
